Fragment Shader — ما هو، مهامه ومبدأ العمل

المؤلف: IT Sectr نُشر: 2026-06-11 وقت القراءة: 10 دق

Fragment Shader هو مرحلة قابلة للبرمجة في خط أنابيب الرسومات تحدد اللون النهائي لكل جزء (بكسل) من الصورة. وفقاً لـ Khronos Group، 2025، يتلقى شادر الأجزاء بيانات محرفية من Vertex Shader ويقوم بحسابات الإضاءة والنسيج وتأثيرات الألوان. Fragment Shader يُستدعى لكل بكسل، مما يجعله المرحلة الأكثر استهلاكاً للموارد في خط أنابيب الرسومات.

الخلاصة

  • Fragment Shader — مرحلة قابلة للبرمجة في GPU تحدد لون كل بكسل على الشاشة.
  • عدد الاستدعاءات يساوي دقة الشاشة، مما يجعله الحمل الحاسوبي الرئيسي لعملية التصيير.
  • النسيج وإضاءة Phong هما مهمتان نموذجيتان تُنفذان في شادر الأجزاء.
  • GLSL و Metal Shading Language يوفران أدوات قياسية لكتابة Fragment Shader.
  • الأداء لـ Fragment Shader ضروري لتحقيق 60 إطاراً في الثانية في التطبيقات المحمولة.

ما هو Fragment Shader؟

Fragment Shader (شادر الأجزاء أو شادر البكسلات) هو مرحلة قابلة للبرمجة في خط أنابيب الرسومات تحسب اللون النهائي لكل جزء من الصورة. الجزء هو بكسل محتمل يصبح بكسل مرئياً على الشاشة بعد اجتياز اختبارات العمق والقناع.

يتم تنفيذ Fragment Shader بعد التنقيط، عندما تكون البدائيات ثلاثية الأبعاد (المثلثات) قد تحولت بالفعل إلى مجموعة من الأجزاء. يستقبل الشادر سمات محرفية — إحداثيات نسيج، خطوط عمودية، ألوان تم حسابها في Vertex Shader لرؤوس المثلث وتم تحريفها خطياً لكل بكسل داخل المثلث.

تاريخ تطور Fragment Shader

قبل ظهور الشادرات القابلة للبرمجة (قبل DirectX 8 / OpenGL 2.0)، كان حساب لون البكسل يتم بواسطة خط أنابيب ثابت بمجموعة محدودة من العمليات. ظهر Fragment Shader القابل للبرمجة في عام 2001 ووسع قدرات الرسومات بشكل جذري: حصل المطورون على تحكم كامل في لون كل بكسل، مما سمح بتنفيذ إضاءة فوتوغرافية ومواد معقدة وتأثيرات لاحقة.

كيف يعمل Fragment Shader؟

Fragment Shader يُطلق بواسطة GPU لكل جزء يولده المنقّط. كل استدعاء شادر يعالج جزءاً واحداً، يقرأ بيانات الإدخال الخاصة به، ينفذ كود المستخدم ويكتب قيمة الإخراج — لون الجزء بتنسيق RGBA.

بيانات الإدخال والإخراج

تشمل بيانات إدخال Fragment Shader السمات المحرفية من Vertex Shader (إحداثيات نسيج، خطوط عمودية، ألوان)، المتغيرات الموحدة (مصادر الضوء، المصفوفات) وعيّنات النسيج. بيانات الإخراج هي متجه اللون (gl_FragColor في OpenGL ES 2.0 أو متغير معرف من قبل المستخدم في ES 3.0)، الذي يُكتب في مخزن الألوان.

glsl
#version 300 es
precision mediump float;

in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;

void main() {
    fragColor = texture(uTexture, vTexCoord);
}

المهام الرئيسية لـ Fragment Shader

Fragment Shader مسؤول عن الجودة البصرية للصورة. جميع التأثيرات التي يراها المستخدم على الشاشة — اللون، الظلال، الانعكاسات، الشفافية — تُحسب في هذه المرحلة من خط أنابيب الرسومات.

النسيج

العملية الأكثر شيوعاً هي أخذ عينة لون من نسيج باستخدام إحداثيات UV محرفية. Sampler2D والدالة texture() تسمحان بالحصول على لون بكسل من أطلس النسيج. التحكم في الترشيح (ثنائي الخطي، ثلاثي الخطي، متباين الخواص) يتم عبر معاملات العيّنة ويؤثر على وضوح الصورة في زوايا رؤية مختلفة.

إضاءة Phong

نموذج إضاءة Phong يُحسب في Fragment Shader لكل بكسل، مما يعطي انعكاسات أكثر نعومة من الإضاءة الرأسية (تظليل Gouraud). تتضمن إضاءة Phong ثلاثة مكونات: محيطي، منتشر ومرآوي.

glsl
// 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 وتحسينه

أداء Fragment Shader هو العامل الرئيسي الذي يحد FPS في الألعاب المحمولة الحديثة. نظراً لأن الشادر يُستدعى لكل بكسل، حتى الزيادة الصغيرة في تعقيد الكود يمكن أن تؤدي إلى انخفاض ملحوظ في معدل الإطارات.

مشاكل الأداء الرئيسية

  • Overdraw — إعادة رسم نفس البكسل بسبب تداخل الكائنات. حرج بشكل خاص للكائنات شبه الشفافة.
  • الفروع الشرطية — التفرع في Fragment Shader يقلل كفاءة تنفيذ SIMD، حيث تضطر GPU لتنفيذ كلا الفرعين.
  • عينات النسيج — كل عينة نسيج لها زمن انتقال يبلغ عشرات دورات ساعة GPU. تقليل عدد العيّنات يسرّع الشادر.

طرق تحسين Fragment Shader

لـ GPUs المحمولة (Qualcomm Adreno، ARM Mali) يُوصى باستخدام mediump precision لمتغيرات float، دمج عينات النسيج، تطبيق اختبارات early-z لاستبعاد الأجزاء غير المرئية قبل تنفيذ الشادر.

الطريقةالوصفالمكسب
Mediump precisionدقة 16 بت بدلاً من 32 بتحتى 2x سرعة
Early-Zاختبار العمق قبل الشادرتقليل الاستدعاءات
Texture atlasingنسيج واحد بدلاً من عدةتبديلات أقل

Fragment Shader مقابل Vertex Shader: مقارنة

كلا النوعين من الشادرات قابلان للبرمجة من قبل المطور، لكنهما يعملان في مراحل مختلفة من خط الأنابيب ويحلّان مهاماً مختلفة. Fragment Shader أكثر استهلاكاً للموارد بشكل ملحوظ بسبب عدد الاستدعاءات.

المعاملFragment ShaderVertex Shader
عدد الاستدعاءاتملايين (دقة الشاشة)آلاف (عدد الرؤوس)
بيانات الإدخالسمات محرفيةسمات رؤوس
الوظيفة الرئيسيةحساب لون الجزءتحويل الهندسة
الوصول إلى النسيجكامل (عدة عيّنات)محدود
التأثير على الأداءعالي (يعتمد على الدقة)معتدل (يعتمد على الهندسة)

أمثلة كود Fragment Shader

Fragment Shader يمكن أن يكون بسيطاً (أخذ عينة نسيج) أو معقداً (إضاءة متعددة الطبقات). لننظر في مثالين عمليين: نسج أساسي وتأثير تدرج باستخدام الوقت.

النسيج الأساسي في GLSL

glsl
#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);
}

مثال في Metal Shading Language

cpp
#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 بكلمات بسيطة؟

Fragment Shader هو برنامج صغير على GPU يحدد لون كل بكسل على الشاشة. إذا كان Vertex Shader يحدد شكل الكائن، فإن Fragment Shader يحدد كيف يبدو هذا الكائن — النسيج، الإضاءة، اللون.

لماذا Fragment Shader يستهلك الكثير من الموارد؟

Fragment Shader يُستدعى لكل بكسل على الشاشة. على جهاز بدقة 2532x1170 (iPhone) هذا تقريباً 3 ملايين استدعاء لكل إطار. عند 60 FPS، يُنفذ الشادر 180 مليون مرة في الثانية، مما يتطلب قوة حاسوبية هائلة.

ما التأثيرات التي يمكن عملها في Fragment Shader؟

في Fragment Shader تُنفذ: النسيج، الإضاءة (Phong، PBR)، الظلال، الانعكاسات، الانكسارات، bloom، عمق المجال، تصحيح الألوان، مرشحات LUT والتوليد الإجرائي للنسيج.

كيف تحسّن Fragment Shader على الأجهزة المحمولة؟

استخدم mediump precision للـ float، قلّل عدد عيّنات النسيج، طبّق early-z culling، ادمج عمليات الشادر وتجنب الفروع الشرطية داخل الشادر.

ما الفرق بين Fragment Shader و Pixel Shader؟

هما نفس الشيء. يُستخدم مصطلح Fragment Shader في OpenGL / Vulkan، بينما يُستخدم Pixel Shader في مصطلحات Direct3D (Microsoft). هما متطابقان وظيفياً: كلاهما يحسب لون كل جزء/بكسل.

الملخص

  • Fragment Shader — مرحلة قابلة للبرمجة في GPU تحسب لون كل بكسل من الصورة.
  • عدد الاستدعاءات يساوي دقة الشاشة، مما يجعله أكثر مراحل التصيير استهلاكاً للموارد.
  • النسيج وإضاءة Phong والتأثيرات اللاحقة هي المهام الرئيسية لشادر الأجزاء.
  • الأداء يعتمد بشكل مباشر على عدد عيّنات النسيج واستخدام highp precision.
  • Mediump precision واختبارات early-z هما أسلوبا التحسين الرئيسيان لـ GPUs المحمولة.
  • OpenGL ES يستخدم مصطلح Fragment Shader، Direct3D يستخدم Pixel Shader — المعنى نفسه.
  • GLSL و Metal Shading Language هما اللغتان الرئيسيتان لكتابة Fragment Shader في التطوير المحمول.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا