الإضاءة المتعددة : دورة OpenGL لغة c++

الإضاءة المتعددة هي استخدام أكثر من مصدر ضوء في تمثيل الإنعكاسات

تسمح الإضاءة المتعددة بإستخدام 6 أضواء مختلفة وانعكاسات مثل Directional و point light.

بالتالي سوف تتمثل صفحة GLSL مزيدا من الإعدادات السابقة والمدمجة في المكتبة.

يمكن استخدام وظائف منفصلة (Functions) في ملفات fragment shader ، وذلك لكي نتمكن من تمثيل كل ضوء على حدا.

عند استخدام الإضاءة المتعددة فإننا نمتلك مخرجات لكل ضوء يتمثل بقيمة output من ملفات model.frag.

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

 

 

 


يتمثل استخدام الإضاءة المتعددة في تطبيق الحلقات التكرارية والوظائف لأول مرة في ملفات GLSL.

 


 تمثيل الإضاءة المتعددة


لكي نبدأ بتمثيل الإضاءة على نحو مطلوب في ملف model.frag نقوم بمسح كافة قيم model.frag ثم نبدأ بتعريف المتغيرات التالية:

#version 330 core
struct Material {
    sampler2D diffuse;
    sampler2D specular;
    float shininess;
};

لا تنسى إضافة إصدار الملف version 330 core عند مسح كافة القيم ، على سبيل المثال تمثل القيم السابقة ملفات النسيج التي سوف يتم التأثير عليها في الإنعكاسات.

struct Dir Light {
    vec3 direction;
    
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

بينما يمثل الــ structure السابق متغيرات تمثيل الإضاءة باستخدام Directional lights التي تحدثنا عنها في الدروس السابقة. بالتالي سوف تحتل حسابات متكررة في دالة main.

struct PointLight {
    vec3 position;
    
    float constant;
    float linear;
    float quadratic;
    
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

يشير الــ structure السابق مجموعة من المتغيرات التي سوف يتم تطبيقها على ممثل Point light ، حيث يتم الاعتماد عليها كثيرا في محركات الرسم.

#define NR_POINT_LIGHTS 4

in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords;

out vec4 color;

uniform vec3 viewPos;
uniform DirLight dirLight;
uniform PointLight pointLights[NR_POINT_LIGHTS];
uniform Material material;

نضع بعين الإعتبار أن المتغير الأول في القيم السابقة يشير إلى نقاط الضوء الأربعة التي سوف يتم إدراجها في فضاء الرسم ، بينما يدل كل يونيفورم على أنواع الإضاءة التي سوف يتم استخدامها في هذا الدرس.

vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);

بما أننا سوف نستخدم نوعين محددين من معادلات الإضافة وهما Point Light و Directional light سوف نقوم بإدراج كل منهما في وظيفة منفصلة على النحو التالي:

vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);

 


تعيين الوظائف في ملف model.frag


يتم تعيين الوظائف في دالة void main الخاصة بملف model.frag. على سبيل المثال K فإن جميع المعادلات التي تم شرحها بهذه الوحدة تم تطبيقها بنسبة 90% في هذه الدوال.

لا ننسى أن ملفات GLSL تمتلك Syntax خاص بلغة c++.

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

void main()
{
  vec3 norm = normalize(Normal);
    vec3 viewDir = normalize(viewPos - FragPos);
    
    
    vec3 result = CalcDirLight(dirLight, norm, viewDir);
   
    for(int i = 0; i < NR_POINT_LIGHTS; i++)
        result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);    
      
    
    color = vec4(result, 1.0);
}

 

نلاحظ في الكود السابق بأننا قمنا بملئ الإضاءة على الأسطح بواسطة عناصر أساسية.

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

بينما يدل متغير normal على الأسطح التي سوف يتم الاصطدام بها.

لقد تم إجراء معادلة بين حصيلة احتساب متغيرين ، وهما مكان وجود الشعاع ، وأيضًا مكان وجود النموذج بذاته.

وفي الواقع فإن احتساب امتصاص الضوء وانعكاسة يتم بهذه الطرق الحسابية.

تمثل ملفات pipelines دوال متشابهة إلى حد كبير مع لغة c++.

 

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

 

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *