Stream Processors أو Shaders : الشيدرز (المظلّلات) أو الستريم بروسيسورز Stream Processors (معالجات الجدول أو التيّار) هي عبارة عن وحدات معالجة مصغّرة (هي في الواقع خطوط معالجة تعتمد مبدأ SIMD) تقسم في الكروت الدّاعمة لدابركت إكس 9 إلى نوعين:
Pixel Shader: أو مظلّلات البكسل، و هذه مهمّتها إعادة صياغة المساحة اللّونيّة التي تكسو سطح عن طريق إعطائها تدرّجات ضوئيّة أكثر و أدق، و يتم حسابها على أساس الإضاءة التي يتعرّض لها الجّسم أو طبيعة هذا الجّسم.
فمثلاً إذا كان لدينا صورة كرة زرقاء دون تدرّجات لونيّة (أو بتدرّج لوني فقير) ستبدو هذه الكرة أقرب إلى الدائرة منها إلى الكرة، أمّا إذا بعد قيام وحدات البكسل شيدر بالتّعديل على المظهر اللونيّ، سنجد أنّ ما كان يبدو كدائرة أصبح واضحاً للعيان ككرة بشكل لا يقبل النّقاش.
مثال آخر أكثر شيوعاً، وهو سطح الماء للأنهار أو الجداول (أو البحار والمحيطات ..إلخ) إذا نظرنا إلى سطوح الأنهار في الألعاب ذات الغرافكس العالي ودقّقنا النّظر فيها سنلاحظ بوضوح أنّ هذه التأثيرات قد تمّت عن طريق إعطاء تدرّجات ضوئيّة متتالية من اللون الأ.رق، وهو ما يتم بواسطة البكسل شيدرز.
و في الواقع فإنّ أكثر التأثيرات جمالاً و جاذبيّة في الألعاب الثّلاثيّة الأبعاد يعود الفضل فيها إلى الخاصيّة المذكورة.
Vertex Shaders: أو مظلّلات الرؤوس، ويقصد بها رؤوس المضلّعات، ولتوضيح ما هية عمل هذه المظلّلات، سأذكر الكلام التّالي:
إنّ كافة الأشكال الهندسيّة في الألعاب (مربّعات، مثلّثات ..إلخ) والتي تسمّى مضلّعات Polygons يتم حسابها عن طريق تعيين إحداثيّات رؤوس هذه المضلّعات، فمثلاً يتم رسم المثلّث ABC كما يلي:
يتم حساب الإحداثيّات الرأسيّة للنّقطة A، ثمّ الإحداثيّات الأفقيّة ثمّ العموديّة، وبعدها للنّقطة B وبعدها للنّقطة C، وهكذا نكون قد حصلنا على المثلّث، ونفس الأمر بالنسبة للشّكل الرباعي لكن بأربع رؤوس عوضاً عن ثلاثة، والخماسي خمسة، و الدّائرة عدد كبير جدّاً من الرؤوس بحيث يصبح لها عدد كبير من الإضلاع الصغيرة جدّاً التي تجعلها تبدو كدائرة.
مهمّة الفيرتكس شيدر ببساطة هي تحديد إحداثيّات هذه النّقاط.
ونفس الأمر ينظبق على الأشكال الثّلاثيّة الأبعاد كالمكعّب، لكن طبعاً بعدد رؤوس أكثر، كما في الصّورة:
أمّا في كروت الدايركت إكس 10 فلقد تمّ توحيد مظلّلات الرّؤوس مع مظلّلات البكسل، فمثلاً عوضاً عن أن تملك البطاقة 64 مظلّل للبكسل و 30 مظلّل للرؤوس، أصبحت تملك 96 مظلّل موحّد يمكن لأي منها العمل ك مظلّل رؤوس أو مظلّل بكسلات حسب الحاجة، وهو ما أتاح الاستفادة من هذه الوحدات بشكل أفضل، فسابقاً عندما كانت اللّعبة لا تحتاج لكافة مظلّلات البكسل وفي نفس الوقت لا يكفي عدد مظلّلات الرؤوس للقيام بما يلزم، فإنّه لم يكن يمكن بأي شكل كان أن تقوم هذه المظلّلات بمساعدة تلك، نظراً لوجود اختلافات هادويريّة ناجمة عن اختلاف طبيعة تعليمات مظلّلات البكسل عن تعليمات مظلّلات الرؤوس في الدايركت إكس 9، على عكس ما أصبح عليه الوضع من الدايركت إكس 10، حيث أصبح توزيع العمل على المظلّلات حسب الحاجة أمراً ممكناً.
نلاحظ في الصّورة التّالية لكرت من الجّيل السّابع كيف أنّه يملك 8 وحدات مظلّلات للبكسل و 3 أخرى للرّؤوس، وفي الصّورة التي تليها نلاحظ كيف أنّ الكرت (وهو من الجيل التّاسع) يملك 64 وحدة تظليل موحّدة Unified.
ولقد تمّ إضافة نوع جديد من المظلّلات في دايركت إكس 10 و هو الـ Geometric Shaders و الوحدات المسؤولة عنه هي نفس الوحدات المسؤولة عن تظليل البكسل و الرؤوس كونه تمّ توحيدها هاردويريّاً كما ذكرنا في كروت دايركت إكس 10.
تمّ إطلاق اسم Unified Shader Architecture على المعماريّة التي تعتمد توحيد المظلّلات.
و إلى عهد قريب كانت هذه الوحدات تعمل بنفس تردّد المعالج الرّسوميّ، لكن في الأجيال الأخيرة من كروت انفيديا تمّ فصل تردّدها عن تردّد النواة الرسوميّة لغرض رفع تردّدهخا إلى تردّدات أعلى لا تتحمّلها الأنوية الرسوميّة حاليّاً.
الـ ROPs:أو Raster Oprations Pipeline وهذه الوحدات تعتبر أخر مرحلة تمر بها الصّور قبل أن يتم عرضها، حيث تثوم بتحويل الصّور الخام التي تصلها من بيانات ثّلاثيّة الأبعاد إلى صور ثنائيّة الأبعاد تتألّف من عدد معيّن من البكسلات و ثمّ كتابتها على مخزن الإطارات Frame Buffer (الإطارات Frames هي الصّور المتتالية التي تعرض على الشّاشة) والذي هو قسم من ذاكرة الكرت مخصّص لكتابة الإطارات عليه بشكل مؤقّت ريثما يتم عرضها على الشّاشة.
وللمزيد من التّوضيح لنستخدم هذا المثال على فرض أنّ كرت الشّاشة يقوم برسم دائرة..
قبل أن تمر الدّائرة بعمليّة الـ Rasterizaitioin فإنّها لن تكون صورة bitmap أو JPG ..إلخ، بل ستكون عبارة عن مقادير رياضيّة تحدّد شكل هذه الدّائرة،أي أنّها ستكون عبارة عن إحداثيّات مركز الدّائرة و طول نصف قطرها و زاويةالرؤية وميل المستوي الذي يحوي هذه الدّائرة ..إلخ، وهو ما يشبه يسمّى صور فكتور أو Vector Images (و لن أقوم بشرحها أو تبيان أوجه الخلاف حتّى لا يتشعّب الموضوع)، و هو المصطلح المضاد لمصطلح Raster Image والت يهي الصّور العاديّة التي نعرفها و التي تتألّف من بيكسلات متجاورة، ومهمّةوحدات الـ ROPs هي إجراء عمليّة الـ Rasterazation و المتمثّلة بتحويل هذهالبيانات إلى صور ثنائيّة الأبعاد موافقة.
وفي الواقع أن هذه الوحدات لا تعتبر حاليّاً مقياس لقوّة الكرت ذلك أنّها لا تشكّل عنق زجاجة في أي من الكروت الجديدة.
الـ Bus Width: أمّا الـ فهو متعلّق بذاكرة الكرت (الرام الخاصّة به) وهو عدد البيتّات bits التي يتم نقلها خلال نبضة واحدة Clock لذاكرة الكرت.
فمن المعلوم كما ذكرنا أنّ كرت الشّاشة يمتلك ذاكرة رام خاصّة به لا علاقة لها بذاكرة الرّام الخاصّة بجهاز الكمبيوتر.
الـ Bandwidth: أو عرض الحزمة، وهو عبارة عن عرض حزمة ذاكرة الرام الخاصّة بكرت الشّاشة، أو بعبارة أخرى الحد الأقصى من البيانات التي تستطيع الذاكرة تبادلها مع وحدات الكرت الأخرى خلال ثانية واحدة، ويتم حسابها بالعلاقة:
عرض الحزمة = الـ Bus Width الخاص بذاكرة الكرت * تردّد الذّاكرة نفسها *2.
حيث التّردّد هو عدد النبضات في الثّانية.
وفي الواقع فإن معدل نقل البيانات الخاصّ بذاكرة الكرت له أثر كبير جدّاً على أداء الكرت و إظهار قوّته بشكل أكبر.
البكسل Pixel: هو أصغر جزء من الصّورة المرئيّة، أو بعبارة أخرى هو نقطة من الصّورة.
الصّور التّالية توضّح مفهوم البكسل، الصّورة الأولى تتألّف من عدد معين من البكسلات، و الثّانية تتألّف من عدد أكبر منها:
نلاحظ من الصّور كيف أنّ زيادة عدد البكسلات في الصّورة يؤدّي إلى تصغيرها وبالتّالي زيادة وضوح الصّورة، وفي الواقع فإنّ شاشات الكمبيوتر و التّلفاز تتألّف من عدد كبير من البكسلات الأمر الذي يجعلها تبدو واضحة و خالية من النّقاط.
أمّا الريزوليوشن Resolution فهو عدد البكسلات العامودية * البكسلات الأفقيّة، أي مثلاً صورة السمكة الأولى تتألّف من 24 بكسل بالطول و24 بكسل آخر بالعرض أي أنّها تتألّف من 24*24= 576 بكسل، أمّا شاشات الكمبيوتر فتتألّف من عدد أكبر من قبيل:
1024*768
أو:
600*800
إلخ.
الـ Anti-Aliasing: (يجب قراءة الفقرة السابقة قبل قراءة هذه الفقرة) أو مضاد التعرّجات، لننظر إلى الصّورة الإتية:
لنفترض أنّ أبعاد الشّاشة (أقصد الريزوليوشن Resoltion) لا تسمح بتصغير البكسلات التي تتألّف منها الصّورة أكثر من ذلك، وقتها ستواجهنا مشكلة وهي التعرّجات الواضحة على أطراف الشكل، فما العمل؟
لحل هذه المشكل تمّ اختراع التقنيّة المذكورة، حيث أنّ الصّورة السابقة بعد معالجتها ستصبح بهذا الشّكل:
وللمقارنة:
نلاحظ كيف تمّ تمويه التّعرّجات بعد المعالجة بمضاد التّعرّجات AA
و هذا شرح مبسّط لكيف تمّ ذلك:
أولاً لنتذكّر أنّ المشكلة هي أنّه لا يمكننا تصغير البكسلات أكثر ممّا هي عليه، لكن ماذا لو قمنا بأخذ الصّورة من مصدر آخر يستعمل عدد أكبر من البكسلات (و بالتّالي فأنّ حجم البكسلات سيصبح أصغر و التّعرّجات ستصبح أصغر و أقل ملاحظةً) و ثمّ قمنا بحساب المعدّل اللّونيّ لكل أربع بكسلات متجاورة ودمجناها ببكسل واحد(2 بالطّول و 2 بالعرض)، ألا يفترض أن نحصل على تمويه جيّد جدّاً لهذه التعرجات؟
الجواب طبعاً هو نعم، إذ يوم الكرت عند تفعيل الخاصيّة المذكورة بمضاعفة عدد البكسلات التي يتم حسابها ثمّ يتم إيجاد محصّلة لون كل أربع بكسلات و ثمّ دمجهم معاً في بكسل واحد ليظهر على الشّاشة.
ففي المثال المذكور إذا نظرنا إلى هذا البكسل:
عند مضاعفة عدد البكسلات 4 أضعاف سينقسم هذا البكسل إلى 4 بكسلات، ثمّ يتم إيجاد محصّلة كل بكسلين متجاورين رأسيّاً وكل بكسلين متجاورين عموديّاً ودمجهما معاً وهو ما يسمّى (Down-sampling)، بحيث أنّ البكسلات التي كانت بيضاء اللون ستبدو الآن رماديّة، وهو ما يخفّف من أثر التعرّجات المذكورة على النّاظر.
علماً أن ضبط خاصيّة الـ AA على 2x يعني تقسيم كل بكسل إلى أربعة، و 4x إلى 16 وهكذا..
و في الواقع فإن هذه البكسلات الإضافيّة لا يتم حسابها بشكل دقيق و إنّما بشكل تقريبي، وذلك في معظم الأحيان، ذلك أنّها ستدمج ببكسلات أخرى، و هذه البكسلات الإضافيّة (أو بالأحرى الجزئيّة) تسمّى Sub-Pixels.
علماً أنه يوجد أكثر من طريقة لكيفيّة عمل مضاد التعرّحات، لكن الطريقة المذكورة هي المعتمدة في الألعاب وتسمّى Full-Scene Anti-Aliasing أو FSAA ، أمّا الطّرق الأخرى خاصّة بالتصميم و الصّور الفوتوغرافيّة.
الـ TMUs: أو الـ Texture Mapping Units هي وحدات مختصّة بإجراء عمليّات الـ Texturing المشروحة في الفقرة التّالية.
الـ Texturing: أو الإكساء، من المعلوم أنّ الأشكال عند خروجها من ووحدات الـ Vertex ستكون على شكل مثلثات ومربّعات و مكعّبات ..إلخ خام مجرّدة من أي إكساء لوني معيّن، وهذه هي مهمّة وحدات الـ TMUs إذ تقوم هذه الوحدات بإلباس كل شكل أكساء معيّن .
وهذه الأكساءات لا يخترعها كرت الشّاشة، إنّما تكون موجودة ضمن ملف اللّعبة على شكل صور، ويتم تحميل جميع الإكساءات الخاصّة باللّعبة إلى ذاكرة الكرت عند تشغيل اللّعبة، إذ تعتبر ذاكرة الرام الخاصّة بالكرت محط للإكساءات الخام قبل أي شيء آخر، ومقدار ما تتلّطبه لعبة ما من ذاكرة الكرت يعتمد بشكل أساسي على كميّة الإكساءات التي زوّدت بها اللّعبة.
ولقد كانت كروت ATI تعاني من ضعف في هذه الخاصيّة حتّى الجّيل 3xxx حيث قامت بعدها الشّركة بزيادة عدد هذه الوحدات إلى 32، و يعود تفوّق كروت انفيديا على كروت ATI في لعبة كرايسس بشكل كبير إلى كونها بحاجة لقوّة كبيرة من الكرت في هذا المجال.
وسابقاً كان كل عدد مظلّلات البكسل = عدد وحدات الـ ROPs = عدد وحدات الـ TMUs ووقتها كنّا نسمّيها خطوط المعالجة PipeLines ، فمثلاً كان من الشّائع وقتها أن نقول أن الكرت الفلاني يعمل بـ 16 خط معالجة للدّلالة على كرت يحوي 16 مظلّل بكسل و 1666 وحدة ROP و 16 وحدة TMU، وهكذا..
Pixel Fillrate: أو نسبة تعبئة البكسل، وهو أكبر عدد من البكسلات يستطيع إخراجه كرت ما خلال ثانية واحدة، و بما أنّ المسؤول عن إخراج الصّورة على شكل بكسلات هو وحدات الـ ROPs كما ذكرنا فإنّ حساب هذا العدد يتم بضرب عدد وحدات الـ ROPs بتردّدها والذي يساوي تردّد الكرت في معظم الأحيان (و هو ما لست متأكدّاً منه تماماً).
الـ Texels: من المعلوم أنّ كلمة Pixel هي اختصار لكلمة Picture Eliment أي عنصر صورة بالعربيّة، الـ Texel هو ببساطة اختصار لكلمة Texture Eliment، أي عنصر إكساء، و هو عدد بكسلات صور الإكساءات التي يتم إكساءها خلال ثانية واحدة. و قراءة المقطع اللّاحق ستعطي فهم أوضح و أدق لما يقصد بـ: "عنصر إكساء" أو Texel.
Fillrate Texel: أو نسبة تعبئة التكسل، و هو في الواقع عدد بيكسلات الـ Textures التي يستطيع الكرت إكسائها على المضلّعات و المجسّمات خلال ثانية واحدة..
إذ أنّ الـ Textures أو الإكساءات الخام في ملفّ اللّعبة هي عبارة عن صور بامتداد bitmap ، فلو كان لدينا أكساء مؤلّف من صورة تتألّف من 400000 بكسل ( أي مثلاً دقّتها 2000*2000بكسل) يريد الكرت تلبيسها (أو بكلمة أخرى إكساءها) مثلاُ على مثلّث مؤلّف من 40 بكسل فإن عدد الـ Texels في هذه الحالة هو 400000 وليس 40.
ولقد ابتكرت بعض التقنيّات للتّخفيف من عدد الـ Texels في مثل هذه الحالة، كتقنيّة الـ MIP Mapping والتي تتلخص بأن يتم تزويد ملف اللّعبة بنسخ متعدّدة من الإكساءات بأبعاد مختلفة، بدءاً من الأبعاد العاديّة للصّورة و انتهاءاً بصورة أبعادها 1*1، ففي هذه الحالة عندما يريد الكرت إكساء شكل ما يتألّف من 66*64 بكسل بصورة معيّنة، فإنّه لا يلجأ إلى الصّورة الأصليّة التي تتألّف من 400000 بكسل، بل يلجأ إلى النّسخة الأقرب لما هو محتاج (66*64 في هذه الحالة)، ولتكن 64 * 64(=4096) ويقوم بإكسائها على الشّكل، ووقتها يكون الكرت قام فقط بـ 64*64= 4096 عمليّة إكساء Texel عوضاً عن 400000، وكما هو واضح فإنّ هذه التقنيّة تزيد الأداء كثيراً كونها توفّر على الكرت القيام بعمليّات إكساء لا حاجة لها، لكن من جهة أخرى فهي تزيد العبئ على ذاكرة الكرت بنسبة لا يستهان بها (قرابة الثّلث تقريباً) وذلك بسبب النماذج الإضافيّة المصغّرة من صورة الإكساء الأصليّة التي سيتم تحميلها على ذاكرة الكرت.
الـ Trilinear Filtering: ذكرنا في الفقرة السّابقة المثال عن إكساء صورة أبعادها 64*64 على سطح أبعاده 66*64، لا بدّ أنّنا نلاحظ تفاوت بين مساحة الصّورة الإكسائيّة و مساحة السطح المراد إكساءه، حسنا ألا يفرض أنّ ذلك سيؤدّي إلى نوع من التشوّه في السطح المكسو؟ الجواب هو نعم طبعاً، وفي حال كان التّفاوت أكبر، كأن نقوم بإكساء صورة بأبعاد 64*64 على سطح بأبعاد 90*60 فوقتها ستبدو التشوّهات أكثر وضوحاً..
تقوم تقنيّة الـ Trilinear Filtering المذكورة بالبحث عن صورتيّ الإكساء ذوات الأبعاد الأقرب إلى أبعاد السطح المراد إكساءه، ثم يتم دمج هاتين الصورتين للحصول على صوررة بأبعاد المطلوبة دون تشوّهات (أو بعبارة أدق بتشوّهات أقلّ)، مثلاً:
نحتاج لإكساء سطح أبعاده 90*90 ، وأقرب صورتين من صورالأكساء لهذه الأبعاد لدينا هي 64*64 و 128*128 ( وهو ما تمّ الحديث عنه في الفقرة السابقة) ثمّ نقوم بإيجاد محصّلة لهاتين الصّورتين أبعادها 90*90 تكون أقرب ما يمكن للصّورة الأكسائيّة.
الـ Bilinear Filtering: وتعمل كالتّالي:
إذا كنّا نريد إكساء صورة بأبعاد 256*256 مثلاً على سطح أبعاده 28*28 مثلاً، فوقتها نلاحظ أنّ كل بكسل يقابله 9 تكسلات Texels (256/28= 9) فما يقوم به كرت الشّاشة في حال تفعيل هذه التقنيّة هو أن يأخذ التكسل Texel الأقرب إلى منتصف كل 9 تكسلات Texels (و في هذه الحالة هو الواقع في المنتصف تماماً على غير ما يحصل في أغلب الحالات كأن تكون لدينا النّسبة 8 إلى واحد) وثمّ يعطي البكسل Pixel لون هذا التكسل الواقع في المنتصف.
وفي حال كان لدينا صورة ذات أبعاد كبيرة جدّاً يتم تصغيرها بهذه الطريقة إلى صورة أصغر بكثير لتلائم سطحاً ما، فإنّ الصورة الإكسائيّة الناتجة عن هذه العمليّة ستبدو مشوّهة بشكل كبير، إذ أنّه في هذه الحالة يتم الاستعاضة عن مجموعة كبيرة من التكسلات بتكسل واحد فقط، وهو ما يؤدّي عند ارتصاف هذه التكسلات بجانب بعضها على الشّاشة إلى ظهور صورة بالكاد تشبه الصّورة الإكسائيّة الأساسيّة.
كان هذا ما يقوم به كرت الشّاشة في الحالة العاديّة، أي بدون تفعيل الـ Bilinear Filterng، أمّا بعد تفعيلها فإنّ ما سيحصل هو قيام كرت الشّاشة بأخذ الأربع تكسلات الموجودة في منتصف البكسل (أي الأربع تكسلات الموجودة في منتصف مجموعة التّكسلات الموافقة لبكسل واحد على شاشة العرض) و دمجها معاً و إعطاء البكسل اللّون النّاتج عن محصّلة ذلك الدّمج.