دوال التشكيل
منطق الـ shader مميز، فهو يختلف عما نعتاد عليه في JavaScript أو لغات البرمجة الأخرى. رغم أن بناء الجملة مشابه، إلا أن طريقة تنفيذ المنطق مختلفة. إنه شبيه بصندوق أسود، تضع فيه بعض البيانات وتحصل منه على ألوان للـ fragment shader، أو مواضع للـ vertex shader.
لكن كيف تتحكم في الناتج؟ كيف تجعله يبدو كما تريد؟ هنا تأتي دوال التشكيل.
سنركز على الـ fragment shader في هذا الدرس، لكن تنطبق نفس المبادئ على الـ vertex shader.
منطقة التدريب
لكي تتقن فن التشكيل، ستحتاج إلى الممارسة والتجربة. سيستغرق الأمر وقتاً للاعتياد على طريقة عمل الـ shader، لكن بمجرد أن تتقنها، ستتمكن من إنشاء تأثيرات مذهلة.
لأنني أريد أن أضعك في أفضل وضع للنجاح، لقد أعددت لك هذا المشهد من معرض فني ثلاثي الأبعاد لتصور الـ shaders الخاص بك في الوقت الفعلي في بيئة ممتعة.
هل يمكنك الشعور بتدفق إبداعك؟ كل تلك الإطارات الفارغة تنتظر روائعك!
النموذج ثلاثي الأبعاد المستخدم هو VR Gallery بواسطة Maxim Mavrichev ومرخص تحت Creative Commons Attribution.
لقد استخدمت <CameraControls />
لإنشاء كاميرا منظور شخص أول للتنقل داخل المعرض و Squoosh لتقليل حجم الخامات.
SimpleShaderMaterial
كل الإطارات في المعرض هي نسخ من SimpleShaderMaterial
، وهو شادر مخصص بسيط أعددته لك مع:
uColor
: لونuTime
: الوقت المنقضي منذ بداية التطبيقvUv
: إحداثيات UV للجزء (من 0 إلى 1 على كلا المحورين)
جميعها موسعة في <App.jsx />
لتتمكن من استخدامها بطريقة إعلانية في مشهدنا.
تمت تسميتها بناءً على موقعها في المعرض، لكن لا تتردد في إعادة تسميتها لشيء أكثر دلالة بمجرد إنشاء روائعك بها!
الدوال
لكل جزء من الشيدر الخاص بنا، سيتم تنفيذ نفس الكود مع مدخلات مختلفة.
إذا أردنا رسم خط، يمكننا استخدام تعبيرات if للتحقق مما إذا كانت البكسل داخل الخط أم لا. ولكن القيام بأشكال أكثر تعقيدًا سيكون صعبًا جدًا وغير فعال.
بدلاً من ذلك، نستخدم الدوال لتشكيل المخرجات. لا تقلق، لا تحتاج لأن تكون خبيرًا في الرياضيات لاستخدامها. تحتاج فقط إلى فهم الدوال المتاحة لك وماذا تفعل.
فكر في الدالة على أنها آلة تأخذ بعض المدخلات وتقدم لك بعض المخرجات. على سبيل المثال، الدالة
f(x) = x * 2
تأخذ رقمًاx
وتعطيكx * 2
كنتيجة.
لتصور تأثير الدوال المختلفة، سنستخدم Graphtoy، وهي أداة بسيطة لكتابة الدوال ورؤية نتائجها. تساعدنا على التأكد من فهمنا للدوال عند تجربتها في الشيدرز الخاصة بنا.
لنقم بتصور دالتنا f(x) = x * 2
في Graphtoy:
سيصبح Graphtoy بسرعة صديقك المفضل عند تجريب الشيدرز.
حان الوقت لتجربة الدوال المختلفة المتاحة لنا.
Step (الدالة الحدية)
تعد الدالة الحدية (step function) دالة بسيطة تعيد 0
إذا كان المدخل أقل من العتبة، و1
إذا كان المدخل أكبر من العتبة.
تأخذ معاملين:
edge
: العتبةx
: قيمة المدخل
لنحاول تطبيقها على الدالة الجزئية ArtFront02Material.jsx
في الشيدر الأمامي:
void main() { float pct = 1.0; pct = step(0.5, vUv.x); vec3 finalColor = pct * uColor; gl_FragColor = vec4(finalColor, 1.0); }
نقوم بإعلان متغير pct
لتحديد نسبة اللون الذي نريد عرضه. نضبطه على 1.0
بشكل افتراضي، ثم نستخدم دالة step
لضبطه على 0.0
إذا كانت vUv.x
أقل من 0.5
.
يمكننا رؤية النصف الأيسر من الإطار باللون الأسود، والنصف الأيمن هو اللون المحدد في الزي الخاص بـ uColor
.
لنقم بتطبيقه على المحور الرأسي مع عتبة مختلفة:
void main() { float pct = 1.0; pct = step(0.2, vUv.y); vec3 finalColor = pct * uColor; gl_FragColor = vec4(finalColor, 1.0); }
يمكننا رؤية 20% من الجزء السفلي للإطار هو أسود، والباقي بنفسجي.
تبدأ إحداثيات UV الأصل في الزاوية السفلى اليسرى للإطار، لذا فإن
[0, 0]
هي الزاوية السفلى اليسرى و[1, 1]
هي الزاوية العليا اليمنى.
إذا كنت ترغب في عكس التأثير، يمكنك ببساطة تبديل معاملات دالة step
:
void main() { float pct = 1.0; pct = step(vUv.y, 0.2); vec3 finalColor = pct * uColor; gl_FragColor = vec4(finalColor, 1.0); }
الآن لدينا التأثير المعاكس.
المزج
دالة mix function هي دالة بسيطة تُرجع تداخلاً خطيًا بين قيمتين.
تأخذ ثلاثة معطيات:
x
: القيمة الأولىy
: القيمة الثانيةa
: القيمة للتداخل بينx
وy
لنجرّب ذلك:
void main() { float pct = 1.0; pct = mix(0.0, 1.0, vUv.x); vec3 finalColor = pct * uColor; gl_FragColor = vec4(finalColor, 1.0); }
يمكننا رؤية تدرج جذاب من الأسود إلى الأرجواني.
كحال العديد من الدوال، يمكنك استخدامها على أنواع أخرى من البيانات، مثل مكونات المتجه. دعونا نستخدمها لإنشاء تدرج من الأبيض إلى الأرجواني على المحور الرأسي:
void main() { vec3 whiteColor = vec3(1.0); vec3 finalColor = mix(whiteColor, uColor, vUv.y); gl_FragColor = vec4(finalColor, 1.0); }
يمكننا رؤية تدرج جذاب من الأبيض إلى الأرجواني.
لنقم بتغيير قيمة التداخل بواسطة استدعاء دالة mix
اولاً للحصول على قيمة pct
، ثم استخدامها للتداخل بين whiteColor
و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); }
اللون الأرجواني فاتح جدًا حيث أن القيمة القصوى لـ pct
هي 0.3
.
استخدم Graphtoy لتجربة دالة mix
وفهم كيفية عملها.
3 تدخلات مختلفة مع دالة mix
تعطي نتائج مختلفة تمامًا.
Smoothstep
دالة smoothstep هي دالة بسيطة تقوم بإرجاع تدرج سلس بين قيمتين.
تأخذ ثلاثة معطيات:
edge0
: الحافة السفليةedge1
: الحافة العلويةx
: القيمة التي يتم التدرج بينها وبينedge0
وedge1
تعطي ثلاثة نتائج مختلفة:
0.0
إذا كانتx
أقل منedge0
1.0
إذا كانتx
أكبر منedge1
- تدرج سلس بين
0.0
و1.0
إذا كانتx
بينedge0
وedge1
لنستخدمها لتغيير قيمة pct
لدينا:
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); }
الانتقال الآن فقط بين 0.4
و 0.6
. كل ما هو دونه أبيض وكل ما هو فوقه أرجواني.
Min & Max
الوظيفتان min
و max
هما دوال بسيطة تعيد القيمة الدنيا أو القصوى بين مدخلين. تعمل تمامًا مثل دوال Math.min
و Math.max
في JavaScript.
لنجعلهم يقومون بتعديل قيمة pct
لدينا بدقة. أولاً، لنتأكد من أنها لا تنخفض أبدًا عن 0.4
(مما يعني أنها ليست بيضاء تمامًا):
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); }
وألا تتجاوز أبدًا 0.6
(مما يعني أنها ليست بنفسجية تمامًا):
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); }
الألوان باهتة، والانتقال سلس للغاية.
لنقوم بتصويرها على Graphtoy:
تمثيل max(x, 0.4)
تمثيل min(x, 0.6)
وإذا جمعناهم:
يمكنك رؤية أن قيمنا لا تنخفض أبدًا عن 0.4
ولا تتجاوز أبدًا 0.6
.
يمكن استبدال تركيبتنا من الدوال
min
وmax
باستخدام دالة clamp، والتي تعتبر اختصارًا لـmin(max(x, min), max)
.
العمليات والأنماط
قبل أن نكتشف العديد من الوظائف المفيدة الأخرى، دعونا نرى كيف يمكننا استخدام العمليات لإنشاء أنماط.
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.