دوال التشكيل

Starter pack

منطق الـ 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

سيصبح 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.

تمثيل دالة step

يمكننا رؤية النصف الأيسر من الإطار باللون الأسود، والنصف الأيمن هو اللون المحدد في الزي الخاص بـ uColor.

لنقم بتطبيقه على المحور الرأسي مع عتبة مختلفة:

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

تمثيل دالة step العمودية

يمكننا رؤية 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);
}

تمثيل دالة step بالعكس

الآن لدينا التأثير المعاكس.

المزج

دالة 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

اللون الأرجواني فاتح جدًا حيث أن القيمة القصوى لـ pct هي 0.3.

استخدم Graphtoy لتجربة دالة mix وفهم كيفية عملها.

دالة 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);
}

Smoothstep function representation

الانتقال الآن فقط بين 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);
}

عامل دالة Min & Max

الألوان باهتة، والانتقال سلس للغاية.

لنقوم بتصويرها على Graphtoy:

رسم Max

تمثيل max(x, 0.4)

رسم Min

تمثيل min(x, 0.6)

وإذا جمعناهم:

رسم Min & Max

يمكنك رؤية أن قيمنا لا تنخفض أبدًا عن 0.4 ولا تتجاوز أبدًا 0.6.

يمكن استبدال تركيبتنا من الدوال min و max باستخدام دالة clamp، والتي تعتبر اختصارًا لـ min(max(x, min), max).

العمليات والأنماط

قبل أن نكتشف العديد من الوظائف المفيدة الأخرى، دعونا نرى كيف يمكننا استخدام العمليات لإنشاء أنماط.

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.