مراحل التصيير rendering pipeline

كتبه بركات يوم الثلاثاء, 14 حزيران 2016

في المقالة السابقة تحدثت عن واجهات التصيير الثلاثي الأبعاد بشكل عام، سنتحدث هذه المقالة عن موضوع مهم في الرسوميات وهي مراحل التصيير rendering pipeline، التركيز هنا سيكون فقط على التصيير الآني realtime rendering لأخذ فكرة عامة الموضوع، دون التركيز على API معينة ودون تفاصيل.

مراحل التصيير هي الخطوات الازمة لتصيير صورة ثنائية الأبعاد تراها على الشاشة من مشهد ثلاثي الأبعاد، تتم هذه الخطوات بالتوالي وعلى مراحل بحيث أن ناتج كل خطوة من هذه الخطوات ينتقل للمرحلة التالية وهكذا حتى تنتج الصورة النهائية، لهذا يسمى pipeline تشبيهاً بخطوط الأنابيب، في حالة التصيير الآني فهذه الخطوات تعاد مثلاً 30 أو 60 مرة في الثانية عند تصيير صور متحركة كما في الألعاب، تسمى عدد الإطارات في الثانية frames per second أو فقط FPS.

هذه الخطوات قد تتم في الـsoftware كلياً أو جزئياً على المعالج الرئيسي CPU، حيث كانت الطريقة الشائعة قبل ظهور المعالجات الرسومية ولاتزال تستخدم في نطاق ضيق، حالياً تتم هذه الخطوات غالباً في العتاد hardware وذلك لتسريعها سواءً باستخدام معالجات رسومية متخصصة GPUs على كروت الشاشة، أو باستخدام مثلاً وحدات معالجة رسومية مدمجة في اللوحة الأم أو غالباً في نفس المعالج مثل AMD APU و Intel HD Graphics، لكن الغالب هو استخدام الـGPUs، العتاد نفسه قد يصير المشهد بخطوات ثابتة، fixed function pipeline، أو بخطوات قابلة للبرمجة programmable pipeline، أو كما هو الشائع هجين بينهما، أي أن جزء من هذه المراحل قابل للبرمجة وجزء ثابت.

في حالة العتاد المبني وفق الـfixed function pipeline، فهناك درات مبنية متخصصة تقوم مثلاً بالتحريك، مهام الإضاءة، الإكساء، البكسلة rasterization أي تحويل الصورة المتجهية إلى نقاط، وغيرها من المهام، وتأثرت الواجهات البرمجية الرسومية مثل OpenGL والـDirectX في الإصدارات الأولى بهذا التصميم، إلا أن هذا التصميم يعيبه أنه يتطور ببطئ، فيحتاج مصنعين العتاد وقت طويل لإضافة الميزات لعتادهم وكذلك لتكلفته، لذا لم يعد يصنع العتاد وفق هذا النمط.

الوقت الحالي هو وقت خطوات التصيير القابلة للبرمجة، أي أن جزءً من خطوات التصيير يتم برمجتها باستخدام برامج خاصة تسمى المظللات shaders، مثال لمظلل نقاط vertex shader مكتوب بلغة GLSL وهي اللغة التي تستخدمها مظللات OpenGL (تستخدم DirectX لغة اسمها HLSL):

#version 330 core

layout (location = 0) in vec3 v_local;
uniform mat4 M_pvm;

void main()
{
    gl_Position = M_pvm * vec4(v_local, 1.0f);
}

تُحمل المظللات بعد ترجمتها إلى لغة الآلة الخاصة بالمعالج الرسومي، والذي يحتوي في حالة المعالجات الرسومية على عدد كبير من الأنوية قد يصل لمئات الأنوية وتنفذ تلك المظللات بالتوازي parallel على النقاط والبكسلات، سميت هذه البرامج بالمظللات لأنها أول ما استخدمت استخدمت لإضفاء التأثيرات كالألوان والخامات textures وبقي الإسم على حاله، فليس جميع المظللات الآن تتحكم بالألوان، مايقوم بهذا العمل الآن هو مظلل يسمى في OpenGL بمظلل القطع fragment shader، وفي DirectX يسمى مظلل البكسل pixel shader.

هذا التصميم الذي يسمح لك باستخدام المظللات للتحكم بالتصيير بسط العتاد، وعقد البرمجة قليلاً، لكنه مكن من عمل أشياء وتأثيرات لم يمكن علمها بسهولة في الماضي، تأثرت الـAPIs طبعاً بهذا التصميم لذا تجد أن الإصدارات الحديثة من OpenGL و DirectX تعتمد على المظللات للتصيير، لازالت تدعم تلك الـAPIs الطريقة القديمة fixed pipeline حيث يقوم الدرايفر بمحاكاتها باستخدام المظللات نظراً لأن هناك العديد من التطبيقات القديمة لازالت تستخدمها.

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

لم يتطور هذا العتاد فجأة، بل تطور على عدة مراحل، أنصحك بإلقاء نظرة على هذا العرض التقديمي Evolution of the Programmable Graphics Pipeline لأخذ نظرة على تطور العتاد وخطوات التصيير.

خطوات التصيير تختلف قليلاً باختلاف الـAPI المستخدم، لكنها تتشابه في الكثير من الأشياء التي قد تختلف مسمياتها بين API وآخر، هذه الخطوات باختصار:

  • التطبيق: والذي يجهز معلومات نقاط النموذج المراد تصييره، وكذلك المعلومات التي ستستخدم لاحقاً لتحديد موقع النموذج وشكله النهائي.
  • معالجة النقاط (قابلة للبرمجة): تتم هذه المرحلة، وما يليها، في المعالج الرسومي GPU باستخدام مظلل النقاط، حيث تحدد موقع ومن ثم شكل صورة النموذج النهائية.
  • معالجة الشكل (قابلة للبرمجة، اختيارية): هذه مرحلة اختيارية، يمكنك استخدام مظلل اسمه مظلل الشكل geometry shader لإجراء تعديلات على الشكل الناتج من المرحلة السابقة لحذف أو إضافة أشكال للشكل الحالي.
  • التجميع وبناء الشكل (ثابتة): هذه المرحلة تتم في الـGPU حيث يتم وصل النقاط لبناء النموذج الثلاثي الأبعاد ببعض.
  • البكسلة (ثابتة): في هذه المرحلة تتم بكسلة الشكل الناتج ليتحول من شكل متجهي متصل إلى صورة نقطية.
  • معالجة البكسلات (قابلة للبرمجة): تتم العمليات التي تتحكم في مظهر النموذج من ألوان وإكساء وحسابات الإضاءة وغيرها في هذه المرحلة، حيث يتم التحكم فيها باستخدام مظلل يسمى مظلل البكسلات pixel shader أو مظلل القطع fragment shader حسب الـAPI.
  • الدمج (ثابتة، قابلة للإعداد): حيث يتم دمج النماذج النهائية مع بعض، هذه المرحلة ليست قابلة للبرمجة باستخدام مظللات، لكن يمكن التحكم فيها بتفعيل خصائص وتعطيل خصائص، وتحديد كيف تعمل بعض تلك الخصائص.