المواد وبالانجليزية Material وتشير بأن كل كائن يتفاعل مع الأضواء ويتم التعبير عنه من خلال البريق واللمعان الذي يظهر انعكاس الأنسجة texture في فضاء الرسم 3D.[1]
بعض المواد تتفاعل مع الانعكاس دون تشتت و بإحداثيات انعكاس كبيرة بالتالي في حال أردنا محاكاة المواد أثناء الانعكاس فقد وفرت لنا مكتبة OpenGL الكثير من الخيارات لتلك المهمة.[1]
و بالتالي لقد تحدثنا في درس الإضاءة الأساسية عن انعكاس الإضاءة الأساسية على أجسام تحمل ألوان RGB.
وكان الناتج هو تمثيل الانعكاس بطريقة أكثر من رائعة عن طريق العمل في متجهات dot product و normal vector.[1] يمكننا استخدام المواد في استدعاء جميع عناصر الانعكاسات من خلال عمل structure في ملفات الظلال.[1]
لكي نبدأ بإعداد المواد يتعين علينا إضافة structure في ملف model.frag على النحو التالي:
struct Material { vec3 ambient; vec3 diffuse; vec3 specular; float shininess; }; uniform Material material;
كما تلاحظ في الكود السابق سوف يتم تخزين جميع خصائص المواد في يونيفورم اسمه material يمكننا من التواصل معها.
على سبيل المثال , فإن متجه مادة الانتشار ambient سوف يقوم بتحديد كافة الألوان المنعكسة تحت خاصيته التي تتصف بالإضاءة الخافتة.
وكذلك الأمر بالنسبة إلى خصائص الإضاءة الأخرى فإنه يتم تحديد المواد بناء على خاصية diffuse و specular.
سوف يتم التأثير على خصائص الإضاءة السابقة بواسطة معادلة shininess. بالتالي فهي تعمل على تقوية كل من الإضاءة لكي تتشابه مع العالم الحقيقي إلى حد كبير.
توفر المواد انعكاسات كبيرة ومتنوعة عن طريق أربعة مكونات تحاكي العالم الحقيقي.
لذلك سوف نقوم بإجراء بعض التغييرات على ملفات الظلال المتعلقة بالنموذج model. نقوم الآن بالذهاب إلى model.frag ونقوم بإضافة المعادلات التالية داخل دالة main.
// Ambient vec3 ambient = lightColor * material.ambient; // Diffuse vec3 norm = normalize(Normal); vec3 lightDir = normalize(lightPos - FragPos); float diff = max(dot(norm, lightDir), 0.0); vec3 diffuse = lightColor * (diff * material.diffuse); // Specular vec3 viewDir = normalize(viewPos - FragPos); vec3 reflectDir = reflect(-lightDir, norm); float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess ); vec3 specular = lightColor * (spec * material.specular); vec3 result = ambient + diffuse + specular; color = vec4(result, 1.0f);
سوف تلاحظ أن المعادلات السابقة لا تختلف كثيرًا عن الدرس السابق باستثناء إضفاء مزيدًا من التنظيم على الكود عن طريق structure.
يتبقى مرحلة قادمة وهي الاتصال في خصائص الإضاءة عن طريق يونيفورم من كود المشروع. بالتالي نقوم الآن بنسخ الكود التالي في المشروع.
GLint matAmbientLoc = glGetUniformLocation(lightingShaders->Program, "material.ambient"); GLint matDiffuseLoc = glGetUniformLocation(lightingShaders->Program, "material.diffuse"); GLint matSpecularLoc = glGetUniformLocation(lightingShaders->Program, "material.specular"); GLint matShineLoc = glGetUniformLocation(lightingShaders->Program, "material.shininess"); glUniform3f(matAmbientLoc, 1.0f, 0.5f, 0.31f); glUniform3f(matDiffuseLoc, 1.0f, 0.5f, 0.31f); glUniform3f(matSpecularLoc, 0.8f, 0.8f, 0.8f); glUniform1f(matShineLoc, 32.0f);
تمتلك المواد تأثير كبير على مصادر الضوء أيضا فهي لديها شدة مختلفة لكل انتشار. سوف نقوم بفعل شيء مشابه للدروس السابقة. وعلى فرض أن الإضاءة تمثل متجه من 1.0 سطحي فإن الكود التالي يمثل بعض التعديلات على معادلات model.frag.
vec3 ambient = vec3(1.0f) * material.ambient; vec3 diffuse = vec3(1.0f) * (diff * material.diffuse); vec3 specular = vec3(1.0f) * (spec * material.specular);
لقد تم إنتاج الضوء بشدة عالية عن طريق تحديدها في المعادلات السابقة , ولو تمعنت في ملف model.frag ستلاحظ بأن كل مادة ترجع قيمة مركزة من الضوء.
على سبيل المثال , تؤثر تلك القيم في مصدر الضوء القادم إلى سطح النموذج. تستطيع التعديل في نتائج المعادلات في القيمة result لكي تصبح على النحو التالي:
vec3 result = vec3(0.1f) * material.ambient;
سوف نعمل على التأثر بخصائص الضوء بشكل منفرد لكل مكون من المواد التي تم العمل فيها سابقاً , بالتالي نقوم الآن بعمل structure جديد في ملف model.frag.
struct Light { vec3 position; vec3 ambient; vec3 diffuse; vec3 specular; }; uniform Light light;
نقوم الآن بإجراء تعديل على كافة القيم في دالة main في ملف model.frag. على سبيل المثال , قم باستبدال كافة القيم بالسطور التالية:
vec3 ambient = light.ambient * material.ambient; vec3 diffuse = light.diffuse * (diff * material.diffuse); vec3 specular = light.specular * (spec * material.specular);
سوف تلاحظ بأننا نعمل على إدارة الأضواء عن طريق كود المشروع بدلا من الإكتفاء بقيمة واحدة. عادة ما يحدث هذا المزيج ألوان أكثر واقعية وخاصة عند تفعيل كل يونيفورم.
بالتالي نقوم بإضافة بعض الخصائص إلى كود المشروع مع الإستغناء عن مصادر استقبال الضوء السابقة.
GLint lightAmbientLoc = glGetUniformLocation(lightingShader.Program, "light .ambient"); GLint lightDiffuseLoc = glGetUniformLocation(lightingShader.Program, "light .diffuse"); GLint lightSpecularLoc = glGetUniformLocation(lightingShader.Program, " light.specular"); glUniform3f(lightAmbientLoc, 0.2f, 0.2f, 0.2f); glUniform3f(light DiffuseLoc, 0.5f, 0.5f, 0.5f); // Let’s darken the light a bit to fit the scene glUniform3f(lightSpecularLoc, 1.0f, 1.0f, 1.0f);
المراجع