Fragment Shader هو مرحلة قابلة للبرمجة في خط أنابيب الرسومات تحدد اللون النهائي لكل جزء (بكسل) من الصورة. وفقاً لـ Khronos Group، 2025، يتلقى شادر الأجزاء بيانات محرفية من Vertex Shader ويقوم بحسابات الإضاءة والنسيج وتأثيرات الألوان. Fragment Shader يُستدعى لكل بكسل، مما يجعله المرحلة الأكثر استهلاكاً للموارد في خط أنابيب الرسومات.
الخلاصة
Fragment Shader (شادر الأجزاء أو شادر البكسلات) هو مرحلة قابلة للبرمجة في خط أنابيب الرسومات تحسب اللون النهائي لكل جزء من الصورة. الجزء هو بكسل محتمل يصبح بكسل مرئياً على الشاشة بعد اجتياز اختبارات العمق والقناع.
يتم تنفيذ Fragment Shader بعد التنقيط، عندما تكون البدائيات ثلاثية الأبعاد (المثلثات) قد تحولت بالفعل إلى مجموعة من الأجزاء. يستقبل الشادر سمات محرفية — إحداثيات نسيج، خطوط عمودية، ألوان تم حسابها في Vertex Shader لرؤوس المثلث وتم تحريفها خطياً لكل بكسل داخل المثلث.
قبل ظهور الشادرات القابلة للبرمجة (قبل DirectX 8 / OpenGL 2.0)، كان حساب لون البكسل يتم بواسطة خط أنابيب ثابت بمجموعة محدودة من العمليات. ظهر Fragment Shader القابل للبرمجة في عام 2001 ووسع قدرات الرسومات بشكل جذري: حصل المطورون على تحكم كامل في لون كل بكسل، مما سمح بتنفيذ إضاءة فوتوغرافية ومواد معقدة وتأثيرات لاحقة.
Fragment Shader يُطلق بواسطة GPU لكل جزء يولده المنقّط. كل استدعاء شادر يعالج جزءاً واحداً، يقرأ بيانات الإدخال الخاصة به، ينفذ كود المستخدم ويكتب قيمة الإخراج — لون الجزء بتنسيق RGBA.
تشمل بيانات إدخال Fragment Shader السمات المحرفية من Vertex Shader (إحداثيات نسيج، خطوط عمودية، ألوان)، المتغيرات الموحدة (مصادر الضوء، المصفوفات) وعيّنات النسيج. بيانات الإخراج هي متجه اللون (gl_FragColor في OpenGL ES 2.0 أو متغير معرف من قبل المستخدم في ES 3.0)، الذي يُكتب في مخزن الألوان.
#version 300 es
precision mediump float;
in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;
void main() {
fragColor = texture(uTexture, vTexCoord);
}
Fragment Shader مسؤول عن الجودة البصرية للصورة. جميع التأثيرات التي يراها المستخدم على الشاشة — اللون، الظلال، الانعكاسات، الشفافية — تُحسب في هذه المرحلة من خط أنابيب الرسومات.
العملية الأكثر شيوعاً هي أخذ عينة لون من نسيج باستخدام إحداثيات UV محرفية. Sampler2D والدالة texture() تسمحان بالحصول على لون بكسل من أطلس النسيج. التحكم في الترشيح (ثنائي الخطي، ثلاثي الخطي، متباين الخواص) يتم عبر معاملات العيّنة ويؤثر على وضوح الصورة في زوايا رؤية مختلفة.
نموذج إضاءة Phong يُحسب في Fragment Shader لكل بكسل، مما يعطي انعكاسات أكثر نعومة من الإضاءة الرأسية (تظليل Gouraud). تتضمن إضاءة Phong ثلاثة مكونات: محيطي، منتشر ومرآوي.
// Fragment shader with Phong lighting
in vec3 vNormal;
in vec3 vPosition;
uniform vec3 uLightDir;
uniform vec3 uLightColor;
void main() {
vec3 norm = normalize(vNormal);
float diff = max(dot(norm, uLightDir), 0.0);
fragColor = vec4(uLightColor * diff, 1.0);
}
يتيح Fragment Shader تطبيق معالجة لاحقة: تصحيح الألوان عبر جداول البحث (LUT)، التمويه (blur)، تأثير التوهج (bloom) و tonemapping للتصيير HDR. كل هذه التأثيرات تعمل على مستوى البكسل وتُنفذ في الوقت الفعلي.
أداء Fragment Shader هو العامل الرئيسي الذي يحد FPS في الألعاب المحمولة الحديثة. نظراً لأن الشادر يُستدعى لكل بكسل، حتى الزيادة الصغيرة في تعقيد الكود يمكن أن تؤدي إلى انخفاض ملحوظ في معدل الإطارات.
لـ GPUs المحمولة (Qualcomm Adreno، ARM Mali) يُوصى باستخدام mediump precision لمتغيرات float، دمج عينات النسيج، تطبيق اختبارات early-z لاستبعاد الأجزاء غير المرئية قبل تنفيذ الشادر.
| الطريقة | الوصف | المكسب |
|---|---|---|
| Mediump precision | دقة 16 بت بدلاً من 32 بت | حتى 2x سرعة |
| Early-Z | اختبار العمق قبل الشادر | تقليل الاستدعاءات |
| Texture atlasing | نسيج واحد بدلاً من عدة | تبديلات أقل |
كلا النوعين من الشادرات قابلان للبرمجة من قبل المطور، لكنهما يعملان في مراحل مختلفة من خط الأنابيب ويحلّان مهاماً مختلفة. Fragment Shader أكثر استهلاكاً للموارد بشكل ملحوظ بسبب عدد الاستدعاءات.
| المعامل | Fragment Shader | Vertex Shader |
|---|---|---|
| عدد الاستدعاءات | ملايين (دقة الشاشة) | آلاف (عدد الرؤوس) |
| بيانات الإدخال | سمات محرفية | سمات رؤوس |
| الوظيفة الرئيسية | حساب لون الجزء | تحويل الهندسة |
| الوصول إلى النسيج | كامل (عدة عيّنات) | محدود |
| التأثير على الأداء | عالي (يعتمد على الدقة) | معتدل (يعتمد على الهندسة) |
Fragment Shader يمكن أن يكون بسيطاً (أخذ عينة نسيج) أو معقداً (إضاءة متعددة الطبقات). لننظر في مثالين عمليين: نسج أساسي وتأثير تدرج باستخدام الوقت.
#version 300 es
precision mediump float;
in vec2 vTexCoord;
in vec3 vColor;
uniform sampler2D uDiffuseMap;
out vec4 fragColor;
void main() {
vec4 texColor = texture(uDiffuseMap, vTexCoord);
fragColor = texColor * vec4(vColor, 1.0);
}
#include <metal_stdlib>
using namespace metal;
struct FragmentIn {
float2 texCoord;
float3 normal;
};
fragment float4
fragmentMain(FragmentIn in [[stage_in]],
texture2d<float> tex [[texture(0)]]) {
constexpr sampler s(filter = linear);
float4 color = tex.sample(s, in.texCoord);
return color;
}
الأسئلة الشائعة
Fragment Shader هو برنامج صغير على GPU يحدد لون كل بكسل على الشاشة. إذا كان Vertex Shader يحدد شكل الكائن، فإن Fragment Shader يحدد كيف يبدو هذا الكائن — النسيج، الإضاءة، اللون.
Fragment Shader يُستدعى لكل بكسل على الشاشة. على جهاز بدقة 2532x1170 (iPhone) هذا تقريباً 3 ملايين استدعاء لكل إطار. عند 60 FPS، يُنفذ الشادر 180 مليون مرة في الثانية، مما يتطلب قوة حاسوبية هائلة.
في Fragment Shader تُنفذ: النسيج، الإضاءة (Phong، PBR)، الظلال، الانعكاسات، الانكسارات، bloom، عمق المجال، تصحيح الألوان، مرشحات LUT والتوليد الإجرائي للنسيج.
استخدم mediump precision للـ float، قلّل عدد عيّنات النسيج، طبّق early-z culling، ادمج عمليات الشادر وتجنب الفروع الشرطية داخل الشادر.
هما نفس الشيء. يُستخدم مصطلح Fragment Shader في OpenGL / Vulkan، بينما يُستخدم Pixel Shader في مصطلحات Direct3D (Microsoft). هما متطابقان وظيفياً: كلاهما يحسب لون كل جزء/بكسل.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا