مظلل

المظلل (بالإنجليزية: Shader) في مجال رسوميات الحاسوب هو مجموعة محدودة من الحسابات المخصصة للوصول إلى تأثير جرافيكي معين.

البدايات

ظهرت فكرة المظللات في الإصدارات الأولى من محرك الرسم ريندر مان كحل تصميمي لتمكين مستخدميه من ابتداع مؤثرات رسومية جديدة دون الحاجة إلى إعادة بناء المحرك في كل مرة

. في بادئ الأمر، كانت مهمة المظللات تماماً كما يظهر من اسمها: حساب تظليل ولون كل بكسل من الصورة النهائية. تلى ذلك مظللات تقوم بعمليات أكثر تعقيداً من مجرد حساب الضوء المباشر والطيف اللوني (كالانعكاسات والانكسارات مثلاً). فتمدد المصطلح ليشمل أية عملية مخصصة يتم إضافتها لحسابات اللون النهائي للبكسلات في الصورة النهائية.

تطور المفهوم

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

. كمثال، مظلل يقوم بعكس لون البكسل يقوم ببساطة باستقبال لون البكسل، يحسب معكوسه، ثم يخرج النتيجة الجديدة.
يمكن ربط المظللات مع بعضها في سلسلة من العمليات المتلاحقة لتشكل تأثيراً أكثر تعقيداً مما يمكن تحقيقه بمظلل واحد فقط. اعتماداً على هذا المفهوم الأخير، نجد أن المحركات مثل ريندر مان ومينتال راي تسمح بالتعبير عن المواد Materials باستخدام شجرة من المظللات المرتبطة فيما بينها

. كل مظلل مستقل بذاته، ويمكن إضافته أو إزالته لتعديل النتائج النهائية. من الجدير بالذكر أن هذه الشجرة ككل أيضاً قد تدعى مظلل. فالمفهوم ما زال حراً وتجده مستخدماً حتى للتعبير عن تأثير جرافيكي كامل يتضمن استخدام عدة مظللات معاً لتحقيقه.

المؤثرات الرسومية باستخدام المظللات

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

طريقة تعامل المحركات مع المظللات

بسبب الطبيعة المرنة للمواد المبنية باستخدام المظللات، وحقيقة أن هذه العمليات يجب أن يتم تنفيذها على كل بكسل من الصورة النهائية، فإن الحاجة قد برزت لإيجاد طرق لتسريع تنفيذ هذه المظللات. كمثال، لكل مادة، يتم تشكيل النص الكامل والمكون من الأقسام المختلفة المشكلة لكل مظلل على حدة (مكتوبة بلغة مظللات ريندر مان)، ومن ثم يتم ترجمة هذا النص إلى تعليمات بلغة الآلة قبل تنفيذه بشكل سريع على جميع البكسلات التي يتم معالجتها. هذه الطريقة متبعة في كل من ريندر مان ومينتال راي (التفاصيل الكاملة للعملية أكثر تعقيداً مما تم شرحه هنا - انظر المصادر).
الفكرة تكمن في محاولة تفادي كل العمل الذي يمكن إنجازه مرة واحدة فقط. الوضع مشابه أيضاً في حالة المظللات الفورية (انظر في الأسفل)، إلا أن الموضوع ليس اختيارياً أساساً.

مقارنتها مع المظللات الفورية

لقد أتاح ظهور وتطور معالجات الرسوميات تنفيذ المظللات المخصصة على هذه المعالجات طالما أن هذه المظللات تحترم مجموعة معينة من القيود (تختلف من جيل من المعالجات إلى آخر). إن مفهوم المظلل الفوري بدأ من المفهوم الأساسي للمظلل، إلا أنه أصبح أكثر تعميماً كذلك. فالمظلل الفوري هو ببساطة أي كود مخصص يتم تنفيذه على المعالج الرسومي. من هنا نرى أنه بالإضافة للمظللات التي تعمل على البكسلات، فإنه يوجد أيضاً مظللات تعمل على النقاط (vertices)، ومؤخراً مظللات تعمل على مستوى المجسم ككل، لديها إمكانية تعريف واستحداث مضلعات جديدة ضمن عملية الرسم.
حتى الآن، فإن الواجهات البرمجية للمظللات الفورية (كدايركت ثري دي وأوبن جي إل) تستقبل فقط نصوصاً كاملة مكتوبة بصيغة خاصة تعبر عن كامل برنامج المظلل. هذا الوضع يختلف عن الفكرة الأساسية الموجودة في مظللات ريندر مان.
إن القيود المفروضة على المظللات الفورية ناتجة بسبب طبيعة عملها. إذ أن المشاهد المرسومة بهذه المظللات يجب أن تتم خلال أجزاء صغيرة من الثانية للحفاظ على سلاسة الحركة ضمن المشهد الفوري. لذا نرى الكثير من المعالجات الفورية تقدم عدداً محدوداً من التعليمات الممكن تنفيذها ضمن هذه المظللات، كما أنها قد تعمل بدقة رقمية غير تامة لتسريع الأداء

. المظللات التي تعمل ضمن محركات الرسم للإنتاج عالي الجودة لا تملك هذه القيود لأن رسم الكوادر غير محصور بزمن قصير كذلك في حالة الرسم الفوري.

مظلل لسطح معدني بلغة تظليل ريندرمان

surface metal(float Ka = 1; float Ks = 1; float roughness = 0.1;)
{
  normal Nf = faceforward(normalize(N), I);
  vector V = - normalize(I);
  Oi = Os;
  Ci = Os * Cs * (Ka * ambient() + Ks * specular(Nf, V, roughness));
}

مظلل مينتال راي لتلوين متدرج على سطح مستمر بلغة سي++

DLLEXPORT miBoolean Ramp(miColor *result, miState *state, struct Ramp *paras)
{
  result->r = result->g = result->b = 0;
  result->a = 1;

  int direction = (int)*mi_eval_integer(&paras->direction);
  miColor color1 = *mi_eval_color(&paras->color1);
  miColor color2 = *mi_eval_color(&paras->color2);
  miScalar sharpness = *mi_eval_scalar(&paras->sharpness);
  miScalar coord = *mi_eval_scalar(&paras->coord);
  miScalar s = (sharpness * 0.4999);
  miScalar uC = (state->tex_list[0].x) + (-coord + 0.5);
  miScalar vC = (state->tex_list[0].y) + (-coord + 0.5);

  if (uC > 1) uC = 1;
  if (uC < 0) uC = 0;
  if (vC > 1) vC = 1;
  if (vC < 0) vC = 0;

  switch(direction)
  {
  case 0: 
    result->r = XMIX(color1.r, color2.r, uC);
    result->g = XMIX(color1.g, color2.g, uC);
    result->b = XMIX(color1.b, color2.b, uC);
    break;
  case 1:
    result->r = YMIX(color1.r, color2.r, vC);
    result->g = YMIX(color1.g, color2.g, vC);
    result->b = YMIX(color1.b, color2.b, vC);
    break;
  default: result= 0;
  }
  return miTRUE;
}

مظلل فوري لعكس لون إكساء بلغة التجميع لدايركت ثري دي 9

ps_2_0
def c0, 1, 0, 0, 0
dcl t0.xy
dcl_2d s0
texld r0, t0, s0
add r0, -r0, c0.x
mov oC0, r0