Partikel
Partikel adalah cara yang bagus untuk menambahkan kehidupan ke dalam adegan Anda. Mereka dapat digunakan dalam berbagai cara, seperti salju, hujan, api, asap, atau efek sihir. Mereka sering digunakan untuk menciptakan efek atmosfer, seperti kabut, debu, atau percikan api.
Dalam pelajaran ini, kita akan mengeksplorasi berbagai cara untuk membuat partikel menggunakan Threejs dan React Three Fiber untuk membuat adegan salju malam dengan langit berbintang dan efek salju turun:
Lihat bagaimana kepingan salju jatuh dan bintang-bintang berkelip di langit. ❄️✨
Bintang
Kode awal kita berisi "Pemandangan Musim Dingin Low Poly" oleh EdwiixGG di atas sebuah kubus dan sumber cahaya yang dianimasikan.
Tampak bagus tetapi kita dapat membuatnya lebih menarik dengan menambahkan bintang ke langit.
Mari kita mulai dengan menambahkan bintang ke langit. Cara termudah dengan React Three Fiber adalah menggunakan komponen Stars dari pustaka drei.
Dalam components/Experience.jsx
:
// ... import { Stars } from "@react-three/drei"; export const Experience = () => { // ... return ( <> <Stars /> {/* ... */} </> ); };
Dan voilà, langit kita sekarang dipenuhi dengan bintang gemerlap yang indah!
Kita dapat bermain dengan parameternya seperti factor
untuk menyesuaikan ukuran berdasarkan jarak atau speed
untuk menyesuaikan waktu efek fade.
Lihat dokumentasi untuk semua parameter yang tersedia.
Mari kita periksa bagaimana cara kerjanya dengan melihat kode sumber dari komponen Stars.
Kita dapat melihat bahwa untuk merender bintang mereka menggunakan points yang diisi dengan tiga atribut pada geometri:
position
: untuk menentukan posisi masing-masing bintangcolors
: untuk menentukan warna masing-masing bintangsize
: untuk menentukan ukuran masing-masing bintang
Kemudian sebuah ShaderMaterial kustom bernama StarfieldMaterial
bertanggung jawab menampilkan titik dengan benar berdasarkan nilai atribut dan uniform waktu untuk efek memudar.
Pertama-tama, pendekatan ini sangat bagus, ringan, dan sepenuhnya diproses pada GPU yang berarti Anda dapat memasang jumlah bintang yang sangat besar.
Tetapi secara visual saya melihat dua hal yang dapat ditingkatkan:
- Bintang direpresentasikan sebagai persegi.
- Efek fade disinkronkan di antara semua bintang yang menghasilkan efek berkedip.
Karena kita tidak memiliki kontrol atas aspek-aspek tersebut dengan komponen Stars
, mari buat sistem bintang kita sendiri!
Bintang Kustom
Untuk memiliki kontrol yang lebih mudah atas bintang-bintang, kita akan mengendalikan logika mereka di sisi CPU menggunakan instancing.
Jangan khawatir jika ini bukan cara yang paling dioptimalkan, untuk jumlah bintang yang masuk akal, ini akan baik-baik saja dan jauh lebih fleksibel. Kita akan belajar bagaimana menangani partikel kita di sisi GPU saat kita membangun VFX engine sederhana kita dan saat mempelajari TSL nanti di bab ini.
PS: Instancing masih merupakan cara yang efisien untuk merender sejumlah besar objek dengan geometri yang sama seperti yang terlihat dalam pelajaran optimisasi.
Instances
Mari mulai dengan membuat komponen StarrySky
kita sendiri di file baru components/StarrySky.jsx
:
import { Instance, Instances } from "@react-three/drei"; import { useMemo, useRef } from "react"; import { randFloatSpread } from "three/src/math/MathUtils.js"; export const StarrySky = ({ nbParticles = 1000 }) => { const particles = useMemo( () => Array.from({ length: nbParticles }, (_, idx) => ({ position: [ randFloatSpread(20), randFloatSpread(20), randFloatSpread(20), ], })), [] ); return ( <Instances range={nbParticles} limit={nbParticles} frustumCulled={false}> <planeGeometry args={[1, 1]} /> <meshBasicMaterial /> {particles.map((props, i) => ( <Particle key={i} {...props} /> ))} </Instances> ); }; const Particle = ({ position }) => { const ref = useRef(); return <Instance ref={ref} position={position} />; };
Kita membuat InstancedMesh menggunakan plane geometry yang dikombinasikan dengan mesh basic material.
Berkat komponen <Instance />
dari Drei, kita dapat membuat instance dari mesh ini dan mengendalikan setiap partikel (instance) secara individu.
Sekarang mari kita hilangkan komponen Stars
dengan yang kustom kita di components/Experience.jsx
:
// ... import { StarrySky } from "./StarrySky"; export const Experience = () => { // ... return ( <> <StarrySky /> {/* ... */} </> ); };
Sekarang kita memiliki langit yang kacau ini:
Ini adalah titik awal yang baik!
Ayo sesuaikan ukuran bintang-bintang. Dalam useMemo
yang bertanggung jawab untuk mengatur posisi partikel, kita bisa menambahkan atribut size
:
import { randFloat, randFloatSpread } from "three/src/math/MathUtils.js"; // ... const particles = useMemo( () => Array.from({ length: nbParticles }, (_, idx) => ({ position: [randFloatSpread(20), randFloatSpread(20), randFloatSpread(20)], size: randFloat(0.1, 0.25), })), [] );
Dan dalam komponen Particle
, kita bisa meneruskan atribut size
ini ke komponen Instance
:
const Particle = ({ position, size }) => { const ref = useRef(); return <Instance ref={ref} position={position} scale={size} />; };
Sekarang lebih baik, kita memiliki bintang-bintang dengan ukuran yang berbeda-beda:
Namun kita memiliki masalah, bintang-bintang diposisikan antara -20
hingga 20
menggunakan randFloatSpread(20)
tetapi kita ingin bintang-bintang diposisikan jauh di langit.
Untuk melakukannya, mari kita tetapkan z
selalu pada 0
dan sesuaikan posisi x
agar berada antara 5
dan 15
.
Bintang-bintang kita akan diposisikan secara acak antara 5
dan 15
pada sumbu x
.
Dan agar semua berada di sekitar tengah, kita rotasi posisi y
antara 0
dan 2 * Math.PI
.
Tengahnya tidak akan mengandung bintang, dan bintang-bintang akan tersebar ke segala arah.
Dalam useMemo
yang bertanggung jawab untuk mengatur posisi partikel, kita bisa menyesuaikan atribut position
dan menambahkan atribut rotation
:
const particles = useMemo( () => Array.from({ length: nbParticles }, (_, idx) => ({ position: [randFloat(5, 15), randFloatSpread(20), 0], rotation: [0, randFloat(0, Math.PI * 2), 0], size: randFloat(0.1, 0.25), })), [] );
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.