الجزيئات
الجزيئات هي وسيلة رائعة لإضافة الحياة إلى مشهدك. يمكن استخدامها بطرق متنوعة، مثل الثلج، المطر، النار، الدخان، أو التأثيرات السحرية. غالباً ما تُستخدم لخلق تأثيرات جوية، مثل الضباب، الغبار، أو الشرر.
في هذا الدرس، سنغوص في طرق مختلفة لإنشاء الجزيئات باستخدام Threejs و React Three Fiber لإنشاء هذا المشهد الشتوي الليلي مع سماء مرصعة بالنجوم وتأثير تساقط الثلج:
شاهد كيف تتساقط رقائق الثلج وكيف تتلألأ النجوم في السماء. ❄️✨
النجوم
يحتوي الشيفرة الابتدائية لدينا على هذا "Low Poly Winter Scene" بواسطة EdwiixGG فوق مكعب ومصدر ضوء متحرك.
يبدو رائعاً، ولكن يمكننا جعله أكثر إثارة بإضافة النجوم إلى السماء.
لنبدأ بإضافة النجوم إلى السماء. أبسط طريقة باستخدام React Three Fiber هي استخدام مكون النجوم (Stars component) من مكتبة drei.
في components/Experience.jsx
:
// ... import { Stars } from "@react-three/drei"; export const Experience = () => { // ... return ( <> <Stars /> {/* ... */} </> ); };
ها قد أصبحت سماءنا الآن مليئة بالنجوم اللطيفة المتوهجة!
يمكننا اللعب بمعاييرها مثل factor
لضبط الحجم بناءً على المسافة أو speed
لضبط توقيت تأثير fade.
ارجع إلى الوثائق للحصول على جميع المعايير المتاحة.
لنرى كيف يعمل ذلك في الخلفية من خلال استعراض الشيفرة المصدرية لمكون النجوم.
يمكننا ملاحظة أن لعرض النجوم يتم استخدام points معبأة بثلاث خصائص على الهندسة الفراغية:
position
: لتحديد موقع كل نجمةcolors
: لتحديد لون كل نجمةsize
: لتحديد حجم كل نجمة
ثم يقوم ShaderMaterial مخصص يسمى StarfieldMaterial
بعرض النقاط بشكل صحيح بناءً على قيم الخصائص وuniform الوقت لتأثير التلاشي.
أولاً وقبل كل شيء، هذه الطريقة رائعة، فهي خفيفة الوزن وتتم معالجتها بالكامل على GPU مما يعني أنه بإمكانك وضع عدد كبير من النجوم.
لكنني أرى بشكل بصري شيئان يمكن تحسينهما:
- النجوم ممثلة بشكل مربعات.
- تأثير التلاشي متزامن بين جميع النجوم مما يؤدي إلى تأثير وميض.
لأنه ليس لدينا سيطرة على هذه الجوانب مع مكون Stars
، دعونا نصنع نظام النجوم الخاص بنا!
نجوم مخصصة
لكي نحصل على تحكم أسهل في النجوم، سنقوم بمعالجة منطقها على جانب CPU باستخدام التوجيه.
لا تقلق إذا لم يكن هذا هو الأسلوب الأمثل، فعدد معقول من النجوم سيكون بخير وأكثر مرونة. سوف نتعلم كيفية معالجة الجسيمات على جانب GPU عندما نبني محرك التأثيرات البصرية البسيط (VFX engine) وعند تعلم TSL لاحقاً في هذا الفصل.
ملاحظة: لا يزال التوجيه وسيلة فعالة لعرض عدد كبير من الكائنات بنفس الهندسة كما هو موضح في درس التحسين.
الأمثلة
لنبدأ بإنشاء مكون StarrySky
الخاص بنا في ملف جديد 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} />; };
نحن نقوم بإنشاء InstancedMesh باستخدام plane geometry مدمج مع mesh basic material.
بفضل مكون <Instance />
من Drei، يمكننا إنشاء أمثلة من هذه الشبكة والتحكم في كل جسيم (مثيل) بشكل فردي.
الآن لنستبدل مكون Stars
بمكوننا المخصص في components/Experience.jsx
:
// ... import { StarrySky } from "./StarrySky"; export const Experience = () => { // ... return ( <> <StarrySky /> {/* ... */} </> ); };
لدينا الآن هذا السماء الفوضوية:
إنه بداية جيدة!
لنجعل حجم النجوم مناسبا. في useMemo
المسؤول عن تعيين مواقع الجسيمات، يمكننا إضافة سمة 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), })), [] );
وفي مكون Particle
، يمكننا تمرير سمة size
هذه إلى مكون Instance
:
const Particle = ({ position, size }) => { const ref = useRef(); return <Instance ref={ref} position={position} scale={size} />; };
الآن أصبح لدينا نجوم بأحجام مختلفة:
لكن لدينا مشكلة، النجوم موضوعة بين -20
و 20
باستخدام randFloatSpread(20)
ولكننا نريد أن تكون النجوم موضوعة بعيدا في السماء.
للقيام بذلك، دعنا نحافظ على z
عند 0
دائمًا ونضبط موضع x
ليكون بين 5
و 15
.
ستكون نجومنا موضوعة بشكل عشوائي بين 5
و 15
على المحور x
.
ولكي تكون في جميع أنحاء المركز، نقوم بتدوير الموضع y
بين 0
و 2 * Math.PI
.
لن يحتوي المركز أبدًا على نجوم وستنتشر النجوم في جميع الاتجاهات.
في useMemo
المسؤول عن تعيين مواقع الجسيمات، يمكننا ضبط سمة position
وإضافة سمة 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.