هل تريد معرفة كيفية إضافة القوام ، والإضاءة ، والظلال ، والخرائط العادية ، والكائنات المتوهجة ، والانسداد المحيط ، وغيرها من التأثيرات على لعبتك ثلاثية الأبعاد؟ ! ممتاز تقدم هذه المقالة مجموعة من أساليب التظليل التي يمكنها رفع مستوى رسومات لعبتك إلى آفاق جديدة. أشرح كل أسلوب بطريقة يمكنك من خلالها تطبيق / نقل هذه المعلومات على أي مجموعة أدوات ، سواء كانت Godot أو Unity أو أي شيء آخر.
ك "غراء" بين التظليل ، قررت استخدام محرك اللعبة الممتاز Panda3D و OpenGL Shading Language (GLSL). إذا كنت تستخدم المكدس نفسه ، فستحصل على ميزة إضافية - ستتعلم كيفية استخدام تقنيات التظليل على وجه التحديد في Panda3D و OpenGL.
تدريب
يوجد أدناه النظام الذي استخدمته لتطوير واختبار نموذج التعليمة البرمجية.
الأربعاء
تم تطوير نموذج التعليمة البرمجية واختبارها في البيئة التالية:
- Linux manjaro 4.9.135-1-MANJARO
- سلسلة تقديم OpenGL: GeForce GTX 970 / PCIe / SSE2
- سلسلة إصدار OpenGL: 4.6.0 NVIDIA 410.73
- g ++ (GCC) 8.2.1 20180831
- Panda3D 1.10.1-1
المواد
تحتوي كل مادة من مواد
Blender المستخدمة لإنشاء
mill-scene.egg
.
الملمس الأول عبارة عن خريطة عادية ، والثاني هو خريطة منتشرة. إذا كان الكائن يستخدم القواعد الطبيعية لرؤوسه ، فسيتم استخدام خريطة عادية "باللون الأزرق العادي". نظرًا لحقيقة أن جميع الطُرز لها نفس البطاقات في نفس المواضع ، يمكن تعميم التظليل وتطبيقه على العقدة الجذرية للرسم البياني للمشهد.
لاحظ أن الرسم البياني للمشهد هو إحدى
ميزات تطبيق محرك Panda3D.
إليك خريطة عادية أحادية اللون تحتوي فقط على اللون
[red = 128, green = 128, blue = 255]
.
يشير هذا اللون إلى الوحدة الطبيعية ، مما يشير إلى الاتجاه الإيجابي للمحور z
[0, 0, 1]
.
[0, 0, 1] = [ round((0 * 0.5 + 0.5) * 255) , round((0 * 0.5 + 0.5) * 255) , round((1 * 0.5 + 0.5) * 255) ] = [128, 128, 255] = [ round(128 / 255 * 2 - 1) , round(128 / 255 * 2 - 1) , round(255 / 255 * 2 - 1) ] = [0, 0, 1]
هنا نرى الوحدة العادية
[0, 0, 1]
تحويلها إلى لون أزرق عادي
[128, 128, 255]
، ويتم تحويل اللون الأزرق الصلب إلى وحدة عادية.
تم توضيح ذلك بمزيد من التفصيل في القسم الخاص بتقنيات تراكب الخريطة العادية.
Panda3D
في مثال التعليمات البرمجية هذا ،
يتم استخدام
Panda3D كـ "غراء" بين التظليل. هذا لا يؤثر على التقنيات الموضحة أدناه ، أي أنه يمكنك استخدام المعلومات التي تمت دراستها هنا في أي محرك رص أو لعبة محددة. يوفر Panda3D بعض وسائل الراحة. في المقالة التي تحدثت عنها ، حتى تتمكن من العثور على نظيرها في مجموعتك ، أو إعادة إنشائها بنفسك إذا لم تكن في المجموعة.
تجدر الإشارة إلى أنه تم إضافة
gl-coordinate-system default
و
textures-power-2 down
و
textures-auto-power-2 1
إلى
config.prc
. لا يتم تضمينها في
تكوين Panda3D القياسي.
افتراضيًا ، يستخدم Panda3D نظام إحداثي يمينًا مع محور z تصاعديًا ، في حين يستخدم OpenGL نظام إحداثيات يميني ذو محور ص صاعد.
يسمح لك
gl-coordinate-system default
بالتخلص من التحويلات بين نظامين للإحداثيات داخل تظليل.
يتيح لنا
textures-auto-power-2 1
استخدام أحجام نسيج ليست قوة لاثنين ، إذا كان النظام يدعمهم.
يكون هذا مناسبًا عند إجراء SSAO أو تنفيذ تقنيات أخرى داخل شاشة / نافذة ، لأن حجم الشاشة / النافذة عادة لا يكون قوة لاثنين.
يقلل
textures-power-2 down
من حجم القوام إلى قوة من اثنين إذا كان النظام يدعم فقط القوام بأحجام مساوية لقوى اثنين.
بناء رمز المثال
إذا كنت ترغب في تشغيل نموذج التعليمة البرمجية ، فيجب عليك أولاً إنشاؤه.
يعمل Panda3D على أنظمة Linux و Mac و Windows.
لينكس
ابدأ
بتثبيت Panda3D SDK للتوزيع.
ابحث عن مكان رؤوس Panda3D والمكتبات. على الأرجح ، تقع في
/usr/include/panda3d/
و
/usr/lib/panda3d/
.
ثم استنساخ هذا المستودع وانتقل إلى الدليل الخاص به.
git clone https://github.com/lettier/3d-game-shaders-for-beginners.git
cd 3d-game-shaders-for-beginners
الآن تجميع التعليمات البرمجية المصدر في ملف الإخراج.
g++ \
-c main.cxx \
-o 3d-game-shaders-for-beginners.o \
-std=gnu++11 \
-O2 \
-I/usr/include/python2.7/ \
-I/usr/include/panda3d/
بعد إنشاء ملف الإخراج ، قم بإنشاء ملف قابل للتنفيذ عن طريق ربط ملف الإخراج بتبعياته.
g++ \
3d-game-shaders-for-beginners.o \
-o 3d-game-shaders-for-beginners \
-L/usr/lib/panda3d \
-lp3framework \
-lpanda \
-lpandafx \
-lpandaexpress \
-lp3dtoolconfig \
-lp3dtool \
-lp3pystub \
-lp3direct \
-lpthread
راجع
دليل Panda3D لمزيد من المعلومات.
ماك
ابدأ بتثبيت
Panda3D SDK لنظام التشغيل Mac.
ابحث عن الرؤوس والمكتبات في Panda3D.
ثم استنساخ المستودع وانتقل إلى الدليل الخاص به.
git clone https://github.com/lettier/3d-game-shaders-for-beginners.git
cd 3d-game-shaders-for-beginners
الآن تجميع التعليمات البرمجية المصدر في ملف الإخراج. يلزمك العثور على أدلة الدلائل في Python 2.7 و Panda3D.
clang++ \
-c main.cxx \
-o 3d-game-shaders-for-beginners.o \
-std=gnu++11 \
-g \
-O2 \
-I/usr/include/python2.7/ \
-I/Developer/Panda3D/include/
بعد إنشاء ملف الإخراج ، قم بإنشاء ملف قابل للتنفيذ عن طريق ربط ملف الإخراج بتبعياته.
تحتاج إلى العثور على مكان المكتبات Panda3D.
clang++ \
3d-game-shaders-for-beginners.o \
-o 3d-game-shaders-for-beginners \
-L/Developer/Panda3D/lib \
-lp3framework \
-lpanda \
-lpandafx \
-lpandaexpress \
-lp3dtoolconfig \
-lp3dtool \
-lp3pystub \
-lp3direct \
-lpthread
راجع
دليل Panda3D لمزيد من المعلومات.
نوافذ
ابدأ
بتثبيت Panda3D SDK لنظام التشغيل Windows.
ابحث عن مكان رؤوس Panda3D والمكتبات.
استنساخ هذا المستودع وانتقل إلى الدليل الخاص به.
git clone https://github.com/lettier/3d-game-shaders-for-beginners.git
cd 3d-game-shaders-for-beginners
راجع
دليل Panda3D لمزيد من المعلومات.
إطلاق العرض التوضيحي
بعد بناء نموذج التعليمة البرمجية ، يمكنك تشغيل الملف القابل للتنفيذ أو العرض التوضيحي. هذه هي الطريقة التي تعمل بها على لينكس أو ماك.
./3d-game-shaders-for-beginners
وبالتالي فهي تعمل على ويندوز:
3d-game-shaders-for-beginners.exe
التحكم في لوحة المفاتيح
يحتوي العرض التوضيحي على عنصر تحكم في لوحة المفاتيح يتيح لك تحريك الكاميرا وتبديل حالة التأثيرات المختلفة.
حركة
w
- التحرك في عمق المشهد.a
- تدوير المشهد في اتجاه عقارب الساعة.s
- الابتعاد عن مكان الحادث.d
- تدوير المشهد عكس اتجاه عقارب الساعة.
آثار للتحويل
y
- تمكين SSAO.Shift
+ y
- تعطيل SSAO.u
- إدراج الدوائر.Shift
+ u
- تعطيل ملامح.i
- تمكين ازهر.Shift
+ i
- تعطيل الإزهار.o
- تمكين الخرائط العادية.Shift
+ o
- تعطيل الخرائط العادية.p
- إدراج الضباب.Shift
+ p
- إيقاف الضباب.h
- إدراج عمق المجال.Shift
+ h
- تعطيل عمق المجال.j
- تمكين posterization.Shift
+ j
- تعطيل التحميلk
- تمكين البكسل.Shift
+ k
- تعطيل البيكسل.l
- شحذ.Shift
+ l
- تعطيل الحدة.n
إدراج الحبوب الفيلم.Shift
+ n
- تعطيل فيلم الحبوب.
النظام المرجعي
قبل البدء في كتابة تظليل ، تحتاج إلى التعرف على الأنظمة المرجعية التالية أو أنظمة التنسيق. كل منهم ينزل إلى ما يتم إحضاره من الإحداثيات الحالية لأصل المرجع من
(0, 0, 0)
. بمجرد أن نكتشف ذلك ، يمكننا تحويلها باستخدام نوع من المصفوفة أو مساحة متجه أخرى. عادةً ، إذا كان ناتج التظليل لا يبدو صحيحًا ، فإن السبب هو خلط أنظمة الإحداثيات.
نموذج
يتناسب نظام الإحداثيات الخاص بالنموذج أو الكائن مع أصل النموذج. في برامج النمذجة ثلاثية الأبعاد ، على سبيل المثال ، في Blender ، يتم وضعها عادةً في مركز النموذج.
العالم
مساحة العالم مرتبطة بأصل المشهد / المستوى / الكون الذي قمت بإنشائه.
نظرة عامة
المساحة الإحداثية للعرض نسبة إلى موضع الكاميرا النشطة.
بتر
لقطة مساحة نسبة إلى مركز إطار الكاميرا. جميع الإحداثيات فيه متجانسة وفي الفاصل
(-1, 1)
. X و y متوازيان مع فيلم الكاميرا ، والإحداثي z هو العمق.
يتم قطع أو التخلص من جميع القمم التي لا تقع داخل حدود هرم الرؤية أو رؤية الكاميرا. نرى كيف يحدث هذا مع مكعب تم اقتطاعه خلف الطائرة البعيدة للكاميرا ، ومكعب موجود على الجانب.
عرض
مساحة الشاشة (عادة) نسبة إلى الركن الأيسر السفلي من الشاشة. يتغير X من الصفر إلى عرض الشاشة. Y يتغير من الصفر إلى ارتفاع الشاشة.
GLSL
بدلاً من العمل مع خط أنابيب من الوظائف الثابتة ، سنستخدم خط أنابيب تقديم GPU قابل للبرمجة. نظرًا لأنه قابل للبرمجة ، يجب علينا نحن أنفسنا تمريره رمز البرنامج في شكل تظليل. التظليل عبارة عن برنامج (عادةً صغير) تم إنشاؤه باستخدام بناء جملة يشبه لغة C. يتكون خط أنابيب GPU القابل للبرمجة من عدة خطوات يمكن برمجتها باستخدام تظليل. أنواع مختلفة من التظليل تشمل تظليل قمة الرأس ، تظليل التغطية بالفسيفساء ، تظليل هندسي ، شظايا والحساب. لاستخدام التقنيات الموضحة في المقالة ، يكفي استخدام الرأس والشظية
مراحل.
#version 140 void main() {}
فيما يلي الحد الأدنى من تظليل GLSL ، الذي يتكون من رقم إصدار GLSL والوظيفة الرئيسية.
#version 140 uniform mat4 p3d_ModelViewProjectionMatrix; in vec4 p3d_Vertex; void main() { gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; }
هنا هو تظليل قمة الرأس المقطوع GLSL ، الذي يحول قمة الرأس المدخلة إلى مساحة القطع ويعرض هذا الموضع الجديد كموضع قمة متناسق.
لا يعيد الإجراء
main
أي شيء ، لأنه
void
، والمتغير
gl_Position
هو الإخراج المضمن.
كلمتين أساسيتين تجدر الإشارة إليهما:
uniform
وفي.
تعني الكلمة الأساسية
uniform
أن هذا المتغير العام هو نفسه بالنسبة لجميع القمم. Panda3D نفسه يعين
p3d_ModelViewProjectionMatrix
ولكل قمة هو نفس المصفوفة.
تعني الكلمة الأساسية
in
أن هذا المتغير العمومي يتم تمريره إلى التظليل. يحصل تظليل قمة الرأس على كل قمة تتألف منها الهندسة ، والتي يربط بها تظليل قمة الرأس.
#version 140 out vec4 fragColor; void main() { fragColor = vec4(0, 1, 0, 1); }
هنا تظليل شظية GLSL المشذب ، يعرض اللون الأخضر الغامق بلون الشظية.
لا تنس أن الجزء يؤثر على بكسل شاشة واحد فقط ، ولكن يمكن أن تؤثر عدة أجزاء على بكسل واحد.
انتبه للكلمة الرئيسية
تعني الكلمة الأساسية
out
أن هذا المتغير العمومي يتم تعيينه بواسطة التظليل.
اسم
fragColor
اختياري ، بحيث يمكنك اختيار أي شيء آخر.
هنا هو إخراج اثنين من تظليل المبين أعلاه.
تقديم الملمس
بدلاً من التقديم / الرسم مباشرةً على الشاشة ، يستخدم نموذج التعليمة البرمجية تقنية لـ
اسم "تقديم إلى نسيج" (تقديم إلى نسيج). للتقديم إلى نسيج ، تحتاج إلى تكوين مخزن مؤقت للإطار وربطه به. يمكنك ربط مواد متعددة بمخزن مؤقت لإطار واحد.
تخزن المواد المنضمة إلى المخزن المؤقت للإطار المتجهات التي يتم إرجاعها بواسطة تظليل التجزئة. عادةً ما تكون هذه المتجهات عبارة عن ناقل لون
(r, g, b, a)
، لكنها يمكن أن تكون إما مواضع أو متجهات عادية
(x, y, z, w)
. لكل نسيج منضم ، يمكن لتظليل الجزء إخراج متجه منفصل. على سبيل المثال ، يمكننا أن نستنتج في أحد المرات وضع قمة الرأس وطبيعته.
الجزء الأكبر من رمز المثال الذي يعمل مع Panda3D يرتبط بتعيين
القوام المخزن المؤقت للإطار . للحفاظ على الأمور بسيطة ، كل تظليل جزء في رمز المثال يحتوي على إخراج واحد فقط. ومع ذلك ، لضمان معدل رتل عالي (FPS) ، نحتاج إلى إنتاج أكبر قدر ممكن من المعلومات في كل تمريرة تقديم.
فيما يلي بنيتان نسيجية للمخزن المؤقت للإطار من نموذج التعليمة البرمجية.
الهيكل الأول يجعل مشهد طاحونة مائية في نسيج عازل للإطار باستخدام مجموعة متنوعة من تظليل الرأس والجزء. يمر هذا الهيكل عبر كل من قمم المرحلة مع الطاحونة وعلى طول الأجزاء المقابلة.
في هذا الهيكل ، يعمل رمز المثال على النحو التالي.
- يحفظ البيانات الهندسية (على سبيل المثال ، الموضع أو قمة الرأس العادية) للاستخدام في المستقبل.
- يحفظ بيانات المواد (مثل اللون المنتشر) للاستخدام في المستقبل.
- ينشئ ربطًا بالأشعة فوق البنفسجية لأنسجة مختلفة (منتشرة ، خرائط عادية ، خرائط الظل ، إلخ).
- يحسب الإضاءة المحيطة والمنتشرة والمنعكسة والمنبعثة.
- يجعل الضباب.
الهيكل الثاني هو كاميرا متعامدة تهدف إلى مستطيل على شكل شاشة.
يعمل هذا الهيكل خلال أربعة قمم فقط وشظاياها المقابلة.
في البنية الثانية ، يقوم نموذج التعليمة البرمجية بتنفيذ الإجراءات التالية:
- يعالج إخراج نسيج العازلة الإطار آخر.
- يجمع بين مختلف القوام العازلة الإطار في واحد.
في مثال الكود ، يمكننا أن نرى مخرجات إطار المخزن المؤقت لإطار واحد ، ونضبط الإطار المقابل على صواب ، وخطأ لجميع الآخرين.
التركيب
التركيب هو ربط اللون أو بعض المتجهات الأخرى بشظية باستخدام إحداثيات الأشعة فوق البنفسجية. تختلف قيم U و V من صفر إلى واحد. يتلقى كل رأس تنسيق إحداثي للأشعة فوق البنفسجية ويتم عرضه في تظليل الرأس.
شادر شظية يحصل على تنسيق الأشعة فوق البنفسجية محرف. الاستيفاء يعني أن تنسيق الأشعة فوق البنفسجية للجزء يقع في مكان ما بين إحداثيات الأشعة فوق البنفسجية من القمم التي تشكل وجه المثلث.
فيرتكس شادر
#version 140 uniform mat4 p3d_ModelViewProjectionMatrix; in vec2 p3d_MultiTexCoord0; in vec4 p3d_Vertex; out vec2 texCoord; void main() { texCoord = p3d_MultiTexCoord0; gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; }
هنا نرى أن تظليل قمة الرأس يخرج إحداثية الملمس إلى تظليل القطعة. لاحظ أن هذا هو ناقل ثنائي الأبعاد: قيمة واحدة لـ U وواحد لـ V.
شظية شظية
#version 140 uniform sampler2D p3d_Texture0; in vec2 texCoord; out vec2 fragColor; void main() { texColor = texture(p3d_Texture0, texCoord); fragColor = texColor; }
هنا نرى أن تظليل القطعة يبحث عن اللون في إحداثيات الأشعة فوق البنفسجية ويعرضه بلون الشظية.
ملء الشاشة الملمس
#version 140 uniform sampler2D screenSizedTexture; out vec2 fragColor; void main() { vec2 texSize = textureSize(texture, 0).xy; vec2 texCoord = gl_FragCoord.xy / texSize; texColor = texture(screenSizedTexture, texCoord); fragColor = texColor; }
عند الرجوع إلى نسيج ما ، تكون الشبكة عبارة عن مستطيل مسطح بنفس نسبة العرض إلى الارتفاع في الشاشة. لذلك ، يمكننا حساب إحداثيات الأشعة فوق البنفسجية ، مع العلم فقط
أ) عرض وارتفاع النسيج مع حجم الشاشة المتراكب على المستطيل باستخدام إحداثيات الأشعة فوق البنفسجية ، و
ب) إحداثيات س و ص للشظية.
لربط x إلى U ، تحتاج إلى تقسيم x على عرض الملمس الوارد. وبالمثل ، لربط y بـ V ، تحتاج إلى تقسيم y على ارتفاع النسيج الوارد. سترى أن هذه التقنية تستخدم في نموذج التعليمات البرمجية.
إضاءة
لتحديد الإضاءة ، من الضروري حساب ودمج جوانب الإضاءة المحيطة والمنتشرة والمنعكسة والمنبعثة. رمز عينة يستخدم الإضاءة فونج.
فيرتكس شادر
لكل مصدر للضوء ، باستثناء الإضاءة المحيطة ، يوفر لنا Panda3D هيكلًا مناسبًا متاحًا لتظليل كل من الرأس والظلال. الشيء الأكثر ملاءمة هو خريطة الظل ومصفوفة لعرض الظلال لتحويل القمم إلى مساحة من الظلال أو الإضاءة.
بدءًا من تظليل قمة الرأس ، يجب علينا تحويل قمة الرأس وإزالتها من مساحة المشاهدة إلى الظل أو مساحة الإضاءة لكل مصدر إضاءة في المشهد. سيكون هذا مفيدًا في المستقبل لتظليل الشظايا لتقديم الظلال. مساحة الظل أو الإضاءة هي مساحة يكون فيها كل إحداثي ذا صلة بموضع مصدر الضوء (الأصل هو مصدر الضوء).
شظية شظية
يقوم جزء التظليل بالجزء الأكبر من حساب الإضاءة.
مادة
يزودنا Panda3D بمواد (في شكل بنية) للشبكة أو النموذج الذي نقدمه حاليًا.
مصادر الإضاءة المتعددة
قبل أن نتجول في مصادر إضاءة المشهد ، سنقوم بإنشاء محرك أقراص يحتوي على ألوان منتشرة وعاكسة.
يمكننا الآن الالتفاف على مصادر الضوء في دورة ما ، بحساب الألوان المنتشرة والألوان المنعكسة لكل منها.
ناقلات الإضاءة ذات الصلة
فيما يلي أربعة متجهات أساسية مطلوبة لحساب الألوان المنعكسة والمنعكسة التي يقدمها كل مصدر للضوء. ناقل اتجاه الإضاءة عبارة عن سهم أزرق يشير إلى مصدر الضوء. المتجه العادي هو سهم أخضر يشير عموديا إلى الأعلى. متجه الانعكاس هو سهم أزرق يعكس متجه اتجاه الضوء. العين أو متجه الرؤية هو السهم البرتقالي الذي يشير إلى الكاميرا.
اتجاه الإضاءة هو المتجه من موضع الرأس إلى موضع مصدر الضوء.
إذا كانت هذه هي الإضاءة الاتجاهية ، فإن Panda3D يعين
p3d_LightSource[i].position.w
الصفر. الإضاءة الاتجاهية لا يوجد لديه موقف ، فقط الاتجاه. لذلك ، إذا كانت هذه هي الإضاءة الاتجاهية ، فإن اتجاه الإضاءة سيكون اتجاهًا سلبيًا أو معاكسًا للمصدر ، لأنه بالنسبة للإضاءة الاتجاهية يحدد
p3d_LightSource[i].position.xyz
إلى
-direction
.
يجب أن يكون الوضع الطبيعي في الرأس متجهًا للوحدة. متجهات الوحدة لها قيمة تساوي واحد.
بعد ذلك ، نحن بحاجة إلى ثلاثة ناقلات أخرى.
نحتاج إلى منتج عددي بمشاركة اتجاه الإضاءة ، لذلك من الأفضل تطبيعه. هذا يعطينا مسافة أو حجم مساوٍ للوحدة (وحدة الموجه).
يكون اتجاه العرض معاكسًا لموضع الرأس / الجزء ، لأن موضع الرأس / الجزء جزء من موضع الكاميرا. لا تنسَ أن موضع قمة الرأس / الجزء هو في مساحة المشاهدة. لذلك ، بدلاً من الانتقال من الكاميرا (العين) إلى الرأس / الجزء ، ننتقل من الرأس / الجزء إلى الكاميرا (العين).
متجه الانعكاس هو انعكاس لاتجاه الإضاءة الطبيعي على السطح. عندما يلمس "شعاع" الضوء السطح ، ينعكس في نفس الزاوية التي سقط فيها. تسمى الزاوية بين متجه الاتجاه للإضاءة والزاوية "زاوية السقوط". تسمى الزاوية بين متجه الانعكاس والعادي "زاوية الانعكاس".
تحتاج إلى تغيير علامة متجه الضوء المنعكس ، لأنه يجب أن يشير في نفس اتجاه متجه العين. لا تنس أن اتجاه العين ينتقل من الجزء العلوي / الجزء إلى موضع الكاميرا. سوف نستخدم متجه الانعكاس لحساب سطوع الضوء المنعكس.
منتشر الإضاءة
سطوع الإضاءة المنتشرة هو نتاج العددية من الطبيعي إلى السطح واتجاه الإضاءة من ناقل واحد. يمكن للمنتج القياسي أن يتراوح من ناقص واحد إلى واحد. إذا أشار كلا الاتجاهين في نفس الاتجاه ، فإن السطوع هو الوحدة. في جميع الحالات الأخرى ، سيكون أقل من الوحدة.
إذا اقترب متجه الإضاءة من نفس الاتجاه كالمعتاد ، عندئذ يميل سطوع الإضاءة المنتشرة إلى الوحدة.
إذا كان سطوع الإضاءة المنتشرة أقل من أو يساوي الصفر ، فأنت بحاجة إلى الانتقال إلى مصدر الإضاءة التالي.
الآن يمكننا حساب اللون المنتشر الذي يقدمه هذا المصدر.
إذا كان سطوع الإضاءة المنتشرة يساوي الوحدة ، فسيكون اللون المنتشر مزيجًا من لون النسيج المنتشر ولون الإضاءة. في أي سطوع آخر ، سيكون اللون المنتشر أغمق.لاحظ أنني أقصر اللون المنتشر بحيث لا يكون أكثر إشراقًا من لون النسيج المنتشر. هذا سيمنع التعرض المفرط للمشهد.الضوء المنعكس
بعد الإضاءة المنتشرة ، يتم حساب الانعكاس.
سطوع الضوء المنعكس هو المنتج القياسي بين متجه العين ومتجه الانعكاس. كما في حالة سطوع الإضاءة المنتشرة ، إذا كان متجهان يشيران في نفس الاتجاه ، فإن درجة سطوع الإضاءة المنعكسة تساوي الوحدة. أي سطوع آخر سوف يقلل من كمية الألوان المنعكسة التي يقدمها مصدر الضوء هذا.يحدد بريق المادة مقدار انتشار الإضاءة المنعكسة. عادة ما يتم ضبطه في برنامج محاكاة ، على سبيل المثال في Blender. في Blender ، يطلق عليه صلابة براق.الأضواء
هذا الرمز لا يسمح للإضاءة بالتأثير على الأجزاء الموجودة خارج مخروط الأضواء أو الهرم. لحسن الحظ، يمكن Panda3D تحديد spotDirection
و spotCosCutoff
للعمل مع أضواء الاتجاه والمكان. الأضواء لديها كل موقف واتجاه. ومع ذلك ، فإن الإضاءة الاتجاهية لها اتجاه فقط ، ومصادر النقاط لها موضع فقط. ومع ذلك ، يعمل هذا الرمز لجميع أنواع الإضاءة الثلاثة دون الحاجة إلى الخلط إذا العبارات. spotCosCutoff = cosine(0.5 * spotlightLensFovAngle);
في حالة إضاءة الإسقاط ، فإن الناتج العددي الخاص بـ "جزء مصدر الإضاءة" الخاص بالناقل ويكون ناقل الاتجاه لجهاز الإسقاط أقل من جيب تمام نصف زاوية مجال رؤيةجهاز الإسقاط ، فلا يأخذ التظليل في الاعتبار تأثير هذا المصدر.لاحظ أنه يجب عليك تغيير علامة unitLightDirection
. unitLightDirection
ينتقل من الجزء إلى الكشاف ، ونحن بحاجة إلى الانتقال من الكشاف إلى الكسر ، لأنه spotDirection
ينتقل مباشرة إلى مركز هرم الكشاف على مسافة معينة من موضع الكشاف.في حالة الإضاءة الاتجاهية والإضاءة الموضعية ، يقوم Panda3D بتعيين spotCosCutoff
القيمة إلى -1. تذكر أن المنتج القياسي يختلف في النطاق من -1 إلى 1. لذلك ، لا يهم ما سيكون عليه unitLightDirectionDelta
، لأنه دائمًا أكبر من أو يساوي -1.
مثل الرمز unitLightDirectionDelta
، يعمل هذا الرمز أيضًا مع جميع أنواع مصادر الإضاءة الثلاثة. في حالة الأضواء ، فإنه سيجعل الشظايا أكثر إشراقًا مع اقترابه من مركز هرم الأضواء. لمصادر الاتجاه ونقطة الضوء spotExponent
هي صفر. تذكر أن أي قيمة لقوة الصفر تساوي الوحدة ، وبالتالي فإن اللون المنتشر يساوي نفسه ، مضروبًا بواحد ، أي أنه لا يتغير.شبح
يعمل Panda3D على تبسيط استخدام الظلال لأنه ينشئ خريطة الظل ومصفوفة تحويل الظل لكل مصدر ضوء في المشهد. لإنشاء مصفوفة تحويل بنفسك ، تحتاج إلى جمع مصفوفة تحول إحداثيات مساحة العرض إلى مساحة الإضاءة (الإحداثيات نسبة إلى موضع مصدر الضوء). لإنشاء خريطة الظل بنفسك ، تحتاج إلى تحويل المشهد من وجهة نظر مصدر الضوء إلى نسيج الإطار المؤقت للإطار. يجب أن يحتوي نسيج الإطار المؤقت على المسافة من مصدر الضوء إلى الأجزاء. وهذا ما يسمى "خريطة العمق". أخيرًا ، تحتاج إلى نقل الخريطة العمق محلية الصنع إلى التظليل يدويًا uniform sampler2DShadow
ومصفوفة تحويل الظل كـ uniform mat4
. لذلك سنقوم بإعادة إنشاء ما يفعله Panda3D تلقائيًا بالنسبة لنا.يتم استخدام مقتطف الشفرة الموضح textureProj
، والذي يختلف عن الوظيفة الموضحة أعلاه texture
. textureProj
الانقسامات الأولى vertexInShadowSpaces[i].xyz
على vertexInShadowSpaces[i].w
. ثم تستخدمه vertexInShadowSpaces[i].xy
للعثور على العمق المخزن في خريطة الظل. ثم تستخدم vertexInShadowSpaces[i].z
لمقارنة عمق الجزء العلوي بعمق خريطة الظل فيه vertexInShadowSpaces[i].xy
. إذا نجحت المقارنة ، textureProj
فتُرجع واحدة. خلاف ذلك ، فإنه يعود صفر. الصفر يعني أن هذه القمة / الشظية في الظل ، وأخرى تعني أن القمة / الشظية ليست في الظل.لاحظ textureProj
أنه يمكن أيضًا إرجاع قيمة من صفر إلى واحد ، اعتمادًا على كيفية تكوين خريطة الظل. في هذا المثالtextureProj
يقوم بإجراء اختبارات عمق متعددة استنادًا إلى الأعماق المجاورة ويعود بمعدل مرجح. هذا المتوسط المرجح يمكن أن يعطي نعومة الظلال.تخفيف
المسافة إلى مصدر الضوء هي ببساطة حجم أو طول متجه اتجاه الإضاءة. لاحظ أننا لا نستخدم الاتجاه الطبيعي للإضاءة ، لأن هذه المسافة ستكون مساوية للوحدة.المسافة إلى مصدر الضوء ضرورية لحساب التوهين. التوهين يعني أن تأثير الضوء بعيدا عن المصدر يتناقص.المعلمات constantAttenuation
، linearAttenuation
و quadraticAttenuation
يمكنك تحديد أي قيمة. الأمر يستحق أن تبدأ constantAttenuation = 1
، linearAttenuation = 0
و quadraticAttenuation = 1
. مع هذه المعلمات ، في موقع مصدر الضوء ، تكون مساوية للوحدة وتميل إلى الصفر عند الابتعاد عنها.إضاءة اللون النهائي
لحساب اللون النهائي للإضاءة ، تحتاج إلى إضافة اللون المنتشر والانعكاس. من الضروري إضافة هذا إلى محرك الأقراص في دورة تجاوز مصادر الضوء في المشهد.المحيطة
يعتمد مكون الإضاءة المحيطة في نموذج الإضاءة على اللون المحيط للمادة ولون الإضاءة المحيطة ولون النسيج المنتشر.لا ينبغي أن يكون هناك أكثر من مصدر إضاءة محيط ، لذلك يجب إجراء هذا الحساب مرة واحدة فقط ، على عكس حسابات الألوان المنتشرة والألوان المنعكسة المتراكمة لكل مصدر للضوء.يرجى ملاحظة أن لون الإضاءة المحيطة يكون مفيدًا عند إجراء SSAO.وضع كل ذلك معا
اللون النهائي هو مجموع اللون المحيط ، اللون المنتشر ، اللون المنعكس ، واللون المنبعث.شفرة المصدر
خرائط طبيعية
يتيح لك استخدام الخرائط العادية إضافة أجزاء جديدة إلى السطح دون هندسة إضافية. عادة ، عند العمل في برنامج النمذجة ثلاثية الأبعاد ، يتم إنشاء إصدارات بولي عالية ومنخفضة للشبكة. ثم تؤخذ في الأساسيات من القمم من شبكة بولي عالية ويخبز في الملمس. هذا الملمس هو خريطة طبيعية. ثم داخل شظايا الشظايا ، نستبدل العناصر الطبيعية لرؤوس شبكة بولي منخفضة بعناصر شبكة بولي عالية مخبوز في الخريطة العادية. نتيجة لهذا ، عند إضاءة شبكة ، يبدو أن لديها مضلعات أكثر مما هي عليه بالفعل. هذا يسمح لك بالحفاظ على FPS عالية ، أثناء نقل معظم التفاصيل من الإصدار عالي الكثافة.هنا نرى الانتقال من نموذج بولي عالي إلى نموذج بولي منخفض ، ومن ثم إلى نموذج بولي منخفض مع خريطة عادية متراكبة.ومع ذلك ، لا تنس أن تراكب الخريطة العادية هو مجرد وهم. في زاوية معينة ، يبدأ السطح في أن يبدو مسطحًا مرة أخرى.فيرتكس شادر
بدايةً من تظليل قمة الرأس ، نحتاج إلى إخراج المتجه العادي ، الموجه ذو الحدين ، وناقل المماس إلى تظليل الشظية. يتم استخدام هذه المتجهات في تظليل الأجزاء لتحويل الصورة الطبيعية للخريطة العادية من مساحة الظل إلى مساحة المشاهدة.p3d_NormalMatrix
يحول المتجهات الطبيعية للناقلات الرأسية والناقلة والشكلية إلى مساحة المشاهدة. لا تنسَ أن جميع الإحداثيات في مساحة العرض متعلقة بموضع الكاميرا.[p3d_NormalMatrix] هي أهم عناصر التبديل العكسي 3x3 في ModelViewMatrix. تستخدم هذه البنية لتحويل المتجه العادي إلى إحداثيات مساحة المشاهدة.
مصدر
نحتاج أيضًا إلى إخراج إحداثيات الأشعة فوق البنفسجية للخريطة العادية إلى تظليل القطعة.شظية شظية
أذكر أن قمة الرأس العادية كانت تستخدم لحساب الإضاءة. ومع ذلك ، لحساب الإضاءة ، الخريطة العادية تعطينا الحالات الطبيعية الأخرى. في التظليل الجزئي ، نحتاج إلى استبدال القواعد الطبيعية للقمم بالمستويات الطبيعية الموجودة في الخريطة العادية.
باستخدام إحداثيات الخريطة العادية التي يتم نقلها بواسطة تظليل قمة الرأس ، نقوم باستخراج القيمة الطبيعية المقابلة من الخريطة.
أعلاه ، لقد أوضحت كيف يتم تحويل الحالات الطبيعية إلى ألوان لإنشاء خرائط طبيعية. نحتاج الآن إلى عكس هذه العملية حتى نتمكن من الحصول على القواعد الأصلية المخبوزة على الخريطة. [ r, g, b] = [ r * 2 - 1, g * 2 - 1, b * 2 - 1] = [ x, y, z]
إليك ما تبدو عليه عملية تفريغ القواعد الطبيعية من الخريطة العادية.
القواعد الطبيعية التي تم الحصول عليها من الخريطة العادية عادة ما تكون في مساحة الظل. ومع ذلك ، يمكن أن يكونوا في مكان آخر. على سبيل المثال ، يسمح لك Blender بخبز الأشياء الطبيعية في مساحة الظل ومساحة الكائن ومساحة العالم ومساحة الكاميرا.لنقل الوضع الطبيعي للخريطة العادية من مساحة الظل إلى مساحة المشاهدة ، قم بإنشاء مصفوفة 3 × 3 بناءً على متجه الظل ، وناقلات ثنائية الشكل ، وقمة الرأس العادية. اضرب العادي بهذه المصفوفة وتطبيعها. هذا هو المكان الذي انتهى بنا الأمر إلى الحالة الطبيعية. لا يزال يتم تنفيذ جميع حسابات الإضاءة الأخرى.شفرة المصدر