Fungsi Pembentukan

Starter pack

Logika shader itu spesial, berbeda dari yang biasa kita gunakan di JavaScript atau bahasa pemrograman lainnya. Meski sintaksisnya mirip, cara kita menerapkan logikanya berbeda. Ini sedikit seperti kotak hitam, Anda memasukkan beberapa data dan mendapatkan beberapa warna untuk fragment shader, atau beberapa posisi untuk vertex shader.

Tetapi bagaimana Anda mengendalikan keluarannya? Bagaimana Anda membuatnya terlihat seperti yang Anda inginkan? Di sinilah fungsi pembentukan masuk.

Kita akan fokus pada fragment shader untuk pelajaran ini, tetapi prinsip yang sama berlaku untuk vertex shader.

Zona Praktik

Untuk menguasai seni pembentukan, Anda akan perlu berlatih dan bereksperimen. Akan butuh waktu untuk terbiasa dengan cara kerja shader, tetapi begitu Anda menguasainya, Anda akan mampu menciptakan efek yang menakjubkan.

Karena saya ingin menempatkan Anda dalam posisi terbaik untuk berhasil, saya telah menyiapkan pemandangan Galeri Seni 3D ini untuk Anda visualisasikan shader Anda secara real-time dalam lingkungan yang menyenangkan.

Apakah Anda merasakan kreativitas Anda mengalir? Semua frame kosong itu menunggu mahakarya Anda!

Model 3D yang digunakan adalah VR Gallery oleh Maxim Mavrichev dan dilisensikan di bawah Creative Commons Attribution.

Saya menggunakan <CameraControls /> untuk membuat kamera orang pertama untuk menavigasi di dalam galeri dan Squoosh untuk mengurangi ukuran tekstur.

SimpleShaderMaterial

Semua bingkai dari galeri adalah salinan dari SimpleShaderMaterial, ini adalah custom shader dasar yang saya siapkan untuk Anda dengan:

  • uColor: sebuah warna
  • uTime: waktu yang berlalu sejak awal aplikasi
  • vUv: koordinat UV dari fragmen (0 hingga 1 pada kedua sumbu)

Semuanya diperluas dalam <App.jsx /> agar dapat digunakan secara deklaratif dalam scene kita.

Mereka dinamai berdasarkan posisi mereka di galeri, tetapi silakan menggantinya dengan nama yang lebih bermakna begitu Anda menciptakan mahakarya dengan mereka!

Fungsi

Untuk setiap fragmen dari shader kita, kode yang sama akan dijalankan dengan input yang berbeda.

Jika kita ingin menggambar garis, kita bisa menggunakan pernyataan if untuk memeriksa apakah pixel berada di dalam garis atau tidak. Namun, membuat bentuk yang lebih kompleks akan sangat sulit dan tidak efisien.

Sebagai gantinya, kita menggunakan fungsi untuk membentuk output kita. Jangan khawatir, Anda tidak perlu menjadi ahli matematika untuk menggunakannya. Anda hanya perlu memahami fungsi apa yang tersedia untuk Anda, dan apa yang mereka lakukan.

Pikirkan fungsi sebagai mesin yang mengambil beberapa input dan memberi Anda beberapa output. Sebagai contoh, fungsi f(x) = x * 2 mengambil angka x dan memberi Anda x * 2 sebagai hasil.

Untuk memvisualisasikan efek dari fungsi yang berbeda, kita akan menggunakan Graphtoy, ini adalah alat sederhana untuk mengetikkan fungsi dan melihat outputnya. Ini membantu memvalidasi pemahaman kita tentang fungsi ketika kita bereksperimen dengan mereka di shader kita.

Mari kita visualisasikan fungsi kita f(x) = x * 2 di Graphtoy:

Graphtoy

Graphtoy akan segera menjadi teman terbaik Anda ketika Anda bereksperimen dengan shader.

Saatnya bereksperimen dengan berbagai fungsi yang tersedia bagi kita.

Step

Fungsi step adalah fungsi sederhana yang mengembalikan 0 jika input kurang dari ambang batas, dan 1 jika input lebih besar dari ambang batas.

Ini membutuhkan dua parameter:

  • edge: ambang batas
  • x: nilai input

Mari mencobanya pada shader fragmen dari frame depan ArtFront02Material.jsx:

void main() {
  float pct = 1.0;
  pct = step(0.5, vUv.x);
  vec3 finalColor = pct * uColor;
  gl_FragColor = vec4(finalColor, 1.0);
}

Kami mendeklarasikan variabel pct untuk menentukan persentase warna yang ingin kita tampilkan. Kami mengaturnya ke 1.0 secara default, dan kemudian kita menggunakan fungsi step untuk mengaturnya ke 0.0 jika vUv.x kurang dari 0.5.

Representasi fungsi Step

Kita dapat melihat setengah kiri dari frame berwarna hitam, dan setengah kanan adalah warna yang diatur dalam uniform uColor.

Mari kita terapkan pada sumbu vertikal dengan ambang batas yang berbeda:

void main() {
  float pct = 1.0;
  pct = step(0.2, vUv.y);
  vec3 finalColor = pct * uColor;
  gl_FragColor = vec4(finalColor, 1.0);
}

Representasi fungsi Step vertikal

Kita dapat melihat 20% dari bagian bawah frame berwarna hitam, dan sisanya berwarna ungu.

Koordinat UV memiliki titik asal di sudut kiri bawah frame, jadi [0, 0] adalah sudut kiri bawah, dan [1, 1] adalah sudut kanan atas.

Jika Anda ingin membalikkan efeknya, Anda bisa cukup menukar parameter fungsi step:

void main() {
  float pct = 1.0;
  pct = step(vUv.y, 0.2);
  vec3 finalColor = pct * uColor;
  gl_FragColor = vec4(finalColor, 1.0);
}

Representasi fungsi Step vertikal dibalik

Sekarang kita memiliki efek yang berlawanan.

Mix

Fungsi mix adalah fungsi sederhana yang mengembalikan interpolasi linear antara dua nilai.

Fungsi ini membutuhkan tiga parameter:

  • x: nilai pertama
  • y: nilai kedua
  • a: nilai untuk diinterpolasi antara x dan y

Mari kita coba:

void main() {
  float pct = 1.0;
  pct = mix(0.0, 1.0, vUv.x);
  vec3 finalColor = pct * uColor;
  gl_FragColor = vec4(finalColor, 1.0);
}

Mix function representation

Kita dapat melihat gradasi yang indah dari hitam ke ungu.

Seperti banyak fungsi lainnya, Anda dapat menggunakannya pada jenis data lain, seperti komponen vektor. Mari kita gunakan untuk membuat gradasi dari putih ke ungu pada sumbu vertikal:

void main() {
  vec3 whiteColor = vec3(1.0);
  vec3 finalColor = mix(whiteColor, uColor, vUv.y);
  gl_FragColor = vec4(finalColor, 1.0);
}

Mix function two colors

Kita dapat melihat gradasi yang indah dari putih ke ungu.

Mari kita ubah nilai interpolasi dengan memanggil fungsi mix untuk pertama kalinya untuk mendapatkan nilai pct, dan kemudian menggunakannya untuk menginterpolasi antara whiteColor dan uColor:

void main() {
  vec3 whiteColor = vec3(1.0);
  float pct = mix(0.0, 0.3, vUv.y);
  vec3 finalColor = mix(whiteColor, uColor, pct);
  gl_FragColor = vec4(finalColor, 1.0);
}

Mix function two colors with pct

Ungu terlihat sangat terang karena nilai maksimum dari pct adalah 0.3.

Gunakan Graphtoy untuk bereksperimen dengan fungsi mix dan memahami cara kerjanya.

Graphtoy mix function

3 interpolasi berbeda dengan fungsi mix memberikan hasil yang sepenuhnya berbeda.

Smoothstep

Fungsi smoothstep adalah fungsi sederhana yang mengembalikan interpolasi halus antara dua nilai.

Fungsi ini mengambil tiga parameter:

  • edge0: batas bawah
  • edge1: batas atas
  • x: nilai yang diinterpolasi antara edge0 dan edge1

Fungsi ini memberikan tiga hasil berbeda:

  • 0.0 jika x kurang dari edge0
  • 1.0 jika x lebih dari edge1
  • interpolasi halus antara 0.0 dan 1.0 jika x berada di antara edge0 dan edge1

Mari kita gunakan untuk mengubah nilai pct kita:

void main() {
  vec3 whiteColor = vec3(1.0);
  float pct = smoothstep(0.4, 0.6, vUv.y);
  vec3 finalColor = mix(whiteColor, uColor, pct);
  gl_FragColor = vec4(finalColor, 1.0);
}

Wildfire

Transisinya sekarang hanya antara 0.4 dan 0.6. Semua yang di bawah adalah putih, dan semua yang di atas adalah ungu.

Min & Max

min dan max adalah fungsi sederhana yang mengembalikan nilai minimum atau maksimum antara dua input. Mereka bekerja persis seperti fungsi Math.min dan Math.max dalam JavaScript.

Mari kita gunakan untuk menyempurnakan nilai pct kita. Pertama, pastikan nilainya tidak pernah di bawah 0.4 (yang berarti tidak pernah benar-benar putih):

void main() {
  vec3 whiteColor = vec3(1.0);
  float pct = smoothstep(0.4, 0.6, vUv.y);
  pct = max(pct, 0.4);
  vec3 finalColor = mix(whiteColor, uColor, pct);
  gl_FragColor = vec4(finalColor, 1.0);
}

Dan tidak pernah di atas 0.6 (yang berarti tidak pernah benar-benar ungu):

void main() {
  vec3 whiteColor = vec3(1.0);
  float pct = smoothstep(0.4, 0.6, vUv.y);
  pct = max(pct, 0.4);
  pct = min(pct, 0.6);
  vec3 finalColor = mix(whiteColor, uColor, pct);
  gl_FragColor = vec4(finalColor, 1.0);
}

Min & Max function representation

Warna terlihat pudar, dan transisinya sangat lembut.

Mari kita visualisasikan pada Graphtoy:

Max graph

Representasi max(x, 0.4)

Min graph

Representasi min(x, 0.6)

Dan jika kita menggabungkannya:

Min & Max graph

Anda dapat melihat nilai kita tidak pernah di bawah 0.4 dan tidak pernah di atas 0.6.

Kombinasi fungsi min dan max kita dapat digantikan oleh fungsi clamp, yang merupakan singkatan dari min(max(x, min), max).

Operasi & pola

Sebelum kita menemukan banyak fungsi berguna lainnya, mari kita lihat bagaimana kita dapat menggunakan operasi untuk membuat pola.

Three.js logoReact logo

React Three Fiber: The Ultimate Guide to 3D Web Development

✨ You have reached the end of the preview ✨

Go to the next level with Three.js and React Three Fiber!

Get full access to this lesson and the complete course when you enroll:

  • 🔓 Full lesson videos with no limits
  • 💻 Access to the final source code
  • 🎓 Course progress tracking & completion
  • 💬 Invite to our private Discord community
Unlock the Full Course – Just $85

One-time payment. Lifetime updates included.