Fungsi Pembentukan
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 warnauTime
: waktu yang berlalu sejak awal aplikasivUv
: 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 angkax
dan memberi Andax * 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 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 batasx
: 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
.
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); }
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); }
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 pertamay
: nilai keduaa
: nilai untuk diinterpolasi antarax
dany
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); }
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); }
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); }
Ungu terlihat sangat terang karena nilai maksimum dari pct
adalah 0.3
.
Gunakan Graphtoy untuk bereksperimen dengan fungsi mix
dan memahami cara kerjanya.
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 bawahedge1
: batas atasx
: nilai yang diinterpolasi antaraedge0
danedge1
Fungsi ini memberikan tiga hasil berbeda:
0.0
jikax
kurang dariedge0
1.0
jikax
lebih dariedge1
- interpolasi halus antara
0.0
dan1.0
jikax
berada di antaraedge0
danedge1
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); }
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); }
Warna terlihat pudar, dan transisinya sangat lembut.
Mari kita visualisasikan pada Graphtoy:
Representasi max(x, 0.4)
Representasi min(x, 0.6)
Dan jika kita menggabungkannya:
Anda dapat melihat nilai kita tidak pernah di bawah 0.4
dan tidak pernah di atas 0.6
.
Kombinasi fungsi
min
danmax
kita dapat digantikan oleh fungsi clamp, yang merupakan singkatan darimin(max(x, min), max)
.
Operasi & pola
Sebelum kita menemukan banyak fungsi berguna lainnya, mari kita lihat bagaimana kita dapat menggunakan operasi untuk membuat pola.
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
One-time payment. Lifetime updates included.