الصفحة الرئيسية/ التقنية / المواد : دورة OpenGL لغة c++ الدرس الخامس عشر

المواد : دورة OpenGL لغة c++ الدرس الخامس عشر


for Large تمت الكتابة بواسطة : محمد



المواد وبالانجليزية Material وتشير بأن كل كائن يتفاعل مع الأضواء ، ويتم التعبير المواد من خلال البريق واللمعان الذي يظهر انعكاس الأنسجة texture في فضاء الرسم 3D.[1]

بعض المواد تتفاعل مع الانعكاس دون تشتت و بإحداثيات انعكاس كبيرة ، بالتالي في حال ما أردنا محاكاة المواد أثناء الانعكاس فقد وفرت لنا مكتبة OpenGL الكثير من الخيارات لتلك المهمة.[1]

 

و بالتالي لقد تحدثنا في درس الإضاءة الأساسية عن انعكاس الإضاءة الأساسية على أجسام تحمل ألوان RGB.

وكان الناتج هو تمثيل الانعكاس بطريقة أكثر من رائعة عن طريق العمل في متجهات dot product و normal vector.[1] 

يمكننا استخدام المواد في استدعاء جميع عناصر الانعكاسات من خلال عمل structure في ملفات الظلال.[1]

 

 

 


لقد قمنا بتغيير أسماء ملفات الظلال lighting لتصبح باسم model.vs و model.frag.

  نبدأ بإعداد المواد لذا يجب علينا إضافة structure في ملف model.frag على النحو التالي:

struct Material {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
uniform Material material;

كما تلاحظ في الكود السابق سوف يتم تخزين جميع خصائص المواد في يونيفورم اسمه material يمكننا من التواصل معه.

على سبيل المثال ، فإن متجه مادة الانتشار ambient يقوم بتحديد كافة الألوان المنعكسة تحت خاصيته التي تتصف بالإضاءة الخافتة.

وكذلك الأمر بالنسبة إلى خصائص الإضاءة الأخرى ، فإنه يتم تحديد المواد بناء على خاصية diffuse و specular.

يتم التأثير على خصائص الإضاءة السابقة بواسطة معادلة shininess.

بالتالي فهي تعمل على تقوية كل من الإضاءة لكي تتشابه مع العالم الحقيقي إلى حد كبير.  


المواد (Material)


توفر المواد انعكاسات كبيرة ومتنوعة عن طريق أربعة مكونات تحاكي العالم الحقيقي.

لذا نقوم بإجراء بعض التغييرات على ملفات الظلال المتعلقة بالنموذج 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);

   

المراجع

  1. [1]^ كتاب ـــــــ offline learn OpenGL created by Joey de Vries.
  2. [2]^ ملف model.frag.
  3. [3]^ كود المشروع من المصادر.

 

وقت النشر : 2023-02-04 21:27:48 ·

1    التصنيفات






2    مقالات من التقنية

يعتمد هذا الموقع على عرض الإعلانات في تحقيق الدخل ، نشكر تفهمكم الدائم ونتمنى لكم قضاء وقت رائع ... وشكراً :D .