ظلال GLSL : دورة OpenGL لغة c++ الدرس السادس

غالبًا ما تشير ظلال GLSL إلى بعض مهام GPU التي تفسرها بطريقة أكثر منها استغلال للموارد.

فهي ليست سوى برامج كود تقوم باستخدام خصائص التحويل بين المدخلات والمخرجات عبر أنابيب الرسم (Pipeline).[1]

وإحدى صفات ظلال GLSL الخاصة هو أنه لا يمكن التواصل معها بشكل دائم ، بالتالي فهي برامج معزولة لا تتمكن حتى من التفاعل مع بعضها البعض.[1]

كل ما تقوم به ظلال GLSL هو إخراج عناصر الألوان من بطاقة العرض عند استلام المهام من وحدة الإدخال.

في الدروس السابقة نستنتج بأن الظلال يمكن إدارتها جيدًا فوق الأسطح.[1]

وخاصة عند وضع المزيد من الخصائص في Vertex Shader و غيرها من الأنابيب.[1]

 

 

ظلال GLSL

تم كتابة الظلال بلغة سي وأطلقت عليها تسمية OpenGl Shading Language على أنها تابع أساسي لمكتبات اللغة.

حيث أنها بذلك مخولة باستخدام المزايا الرائعة وخاصة عند معالجة المصفوفات الكبيرة.[1]

وبالتالي فإن شيفرة الظلال غالبًا ما تبدأ بالإعلان عن المكتبة أولا مع مجموعة من المدخلات والمخرجات في بقية البرنامج.

على سبيل المثال ، نعتبر بأن متغيرات Uniforms واحدة منها.[1]

وبالتالي يتم الإشارة إلى جميع عمليات المعالجة في دالة main الخاصة بالظلال.[1]

وفيما يلي الصيغة العامة لها نقلاً عن المصادر :

#version version_number
in type in_var_name;
in type in_var_name;
out type out_var_name;

uniform type uniform_name;
int main()
{
// Input Processing
...
// Output exported
out_var_name = our_stuff_we_processed;
}

كل متغير في vertex shader يعبر عن صفة ويتسع لـ ظلال GLSL كبيرة من المتغيرات شريطة أن تدعم بطاقة العرض ذلك.[1]

يمكن أن تستوعب البطاقات القديمة لغاية 16 مكون vertex بينما يتضاعف الأمر كثيرا إذا ما قمنا بالنظر إلى البطاقات المتطورة.[1]

ويستطيع المطور فحص مدى دعم الظلال لبطاقة العرض وفقا للكود التالي:

GLint attributes;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, & attributes);
std::cout << \"Maximum number of vertex attributes supported: \" << attributes
<< std::endl;

 

أنواع متغيرات GLSL[1]

تقدم لغة GLSL مجموعة واسعة من المتغيرات التي تم بناؤها بلغة سي .[1]

وبالتالي فإنها تتكون من متغيرات صحيحة وطبقية ومنطقية وغير محدودة.

فيما يلي أنواع المتغيرات بأسمائها:

  • رقمية : المتجه بقيمة رقمية طبقية.
  • المنطقية: وهي مثال على القيم المنطقية.
  •  Integer متغيرات : مثال على قيمة من نوع Integer(أعداد صحيحة).
  • غير محدودة : متغيرات غير معينة (unsigned).
  • ازدواجية : القيم المزدوجة (double).

في ظلال GLSL يمكن الوصول إلى متغيرات المتجهات عن طريق العناصر XYZ W.

على سبيل المثال لو ما أردنا الوصول لقيمة x فإن ذلك يتطلب كتابتها على النحو التالي: vec.x.[1].

تتمتع قيم المتجهات بمرونة عالية جدًا عند التحكم بالألوان والإحداثيات.

و بالتالي يمكن اعتبارها أحد طرق sizzling في تعيين البيانات.[1]

vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;

تمنح طريقة التعيين السابقة بعض العمليات التي يمكن استخدامها أثناء العمل مع لغة GLSL.[1]

على سبيل المثال يدل الكود الأول على تعريف متجه محدد ، بينما تدل العمليات التالية لها على جمع متجهين وإجراء Assigning (مساواة في القيم) وما دون ذلك الكثير من الوظائف المنطقية.[1]

وهنا مثال آخر من المصادر حول طرق استخدام المتجهات في ظلال GLSL.

vec2 myvec = vec2(0.5f, 0.7f);
vec4 result = vec4(myvec , 0.0f, 0.0f);
vec4 otherResult = vec4(result.xyz, 1.0f);

 

المدخلات والمخرجات

يمكن اعتبار الظلال على أنها برامج رائعة بالفعل ، وخاصة أنها تحتل جزء كبير للغاية من عمليات الإدخال والإخراج التي نستخدمها.

يمكن استخدام نوعين من الصيغ المحجوزة فيها مثل in التي تدل على المدخلات بينما out تدل على المخرجات.

على سبيل المثال ، يتعين على كل ظل من ظلال GLSL استخدام عبارات in و out وذلك للتحكم في المدخلات لكل نموذج يتم رسمه.

كما يستقبل vertex shader البيانات بطريقة مختلفة ، وذلك لأنه يقوم باستلامها مع الإحداثيات لمعرفة كم من البيانات التي سوف يتم تحديدها للمراحل القادمة من الأنابيب.

يمكن اعتبار أن vertex shader لا يقتصر على بطاقة GPU فحسب. بل حتى أنه يعطي وحدة CPU الإحداثيات ليتم قراءتها قبل إعداد الرسم.

تشير العبارة location = 0 إلى أن هناك مكان محدد في الذاكرة قيمته صفر يتعين على بقية الظلال التعامل معه في جلب الألوان.

 

من الممكن ارسال قيمة layout (location = 0 ) على أنها محدد فعلي لمكان الرسم. ومن ثم يتعين على شيفرة OpenGL الإشارة إليها من Vertex Shader وحفظها ليتم تمريرها إلى بقية مراحل الظلال.

 

يتعين على مرحلة fragmentShader استقبال متجهات من نوع vec4 ليتم توليد الألوان النهائية للإحداثيات.

وفي حال فشل ربط الألوان سيتم استدعاء الكائنات بألوان بيضاء أو سوداء.

وبالتالي في حال أردنا إرسال البيانات من ظلال GLSL يجب تمريرها بطريقة متكافئة وبنفس الأسماء دون زيادة أو نقصان حينئذ ستنجح عملية الربط بلا شك.

 

مثال على استخدام الظلال

لدينا الآن شيفرة Pipeline من لغة GLSL يجب أن تدرك أن ما تم شرحه سابقًا ستجده في هذه الشيفرة والمسألة لن تصعب عليك بعد الآن.

وفي حال وجدت صعوبة في فهمها يمكنك العودة والقراءة من جديد أو يمكنك انتظار الأمثلة القادمة لتكشف لك كل شيء.

vertex Shader
#version 330 core
layout (location = 0) in vec3 position; // The position variable has
attribute position 0
out vec4 vertexColor; // Specify a color output to the fragment shader
void main()
{
gl_Position = vec4(position, 1.0); // See how we directly give a vec3
to vec4’s constructor
vertexColor = vec4(0.5f, 0.0f, 0.0f, 1.0f); // Set the output variable
to a dark-red color
}

سيتم تمرير مكان الإحداثيات عن طريق layout (location=0) مع مواقعها في الفضاء باستخدام العبارة in يليها متجه باسم position.

السطر التالي يشير إلى تصدير متجه باسم vertexColor سيتم استقباله في مرحلة Fragment Shader.

متغير gl_position ثابت سيستقبل الإحداثيات القادمة من شيفرة OpenGL.

بالتالي يتم تعيين اللون المراد وضعه للنموذج وهو على ما يبدو من إحدى درجات dark red.

fragment shader
#version 330 core
in vec4 vertexColor; // The input variable from the vertex shader (same
name and same type)
out vec4 color;
void main()
{
color = vertexColor;
}

مرحلة fragment Shader تستقبل البيانات عن طريق تعريف متغير من نفس الإسم vertex Color.

ولا ننسى أن عبارة in تعني استقبال المدخلات والتي هي عبارة عن الألوان التي تم تعيينها في شيفرة vertex Shader.

وقد قمنا بتعريف متغير باسم color ومن نوع vec4 يعمل على إرجاع قيمة الألوان إلى شيفرة OpenGL عن طريق تعيين out.

وعند النظر إلى النتائج النهائية باستخدام ظلال GLSL فإن مخرجات الشيفرة الخاصة بناء ستكون على النحو التالي:

\"نتائج

المراجع

  1. [1]^ كتاب ـــــــ offline learn OpenGL created by Joey de Vries.

اترك تعليقاً

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