ABC لتجميع التظليل. طرق التجميع الشائعة

21.04.2019
  • ترجمة

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

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

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

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

كان هذا الأمل هو الذي دفعنا إلى رحلة صعبة مع عدم وجود فرصة للنجاح تقريبًا. رحلة تطلبت عامين من العمل على يد العديد من المتخصصين في معالجات الفيديو. وكل هذا من أجل محاكاة المسار الكامل لخط أنابيب GameCube/Wii الأساسي القابل للبرمجة بدونهذا التجميد المزعج.

كان هذا فجر عصر Ubershaders.

مشكلة

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


معالج الفيديو GameCube Flipper، وهو أكبر شريحة على اللوحة الأم. المصدر: أناندتك

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

يحتوي Flipper على عناصر ذات وظائف ثابتة، لذلك استخدم وحدة TEV (Texture EnVironment) قابلة للبرمجة والتي يمكن تهيئتها لأداء مجموعة كبيرة ومتنوعة من التأثيرات وتقنيات العرض - بنفس الطريقة التي تفعل بها تظليل البكسل. في الواقع، قدرات وحدة TEV تشبه إلى حد كبير قدرات تظليل DirectX 8 بكسل الموجود على Xbox! لقد كان متعدد الاستخدامات وقويًا لدرجة أنه تم استخدام Flipper، مع بعض التعديلات، كمعالج فيديو لجهاز Wii (المعروف الآن باسم Hollywood). لسوء الحظ بالنسبة لنا، تم تصميم وحدة TEV لإجراء تكوينات TEV في الألعاب مباشرة عندما يكون التأثير مطلوبًا. لا يوجد تحميل مسبق لتكوينات TEV لأن وحدة TEV لا تحتوي على ذاكرة لهذا الغرض.

كان هذا التنزيل الفوري هو مصدر كل مشاكلنا. كان على Dolphin ترجمة كل تكوينات Flipper/Hollywood التي تستخدمها اللعبة إلى تظليل متخصص يمكن تنفيذه بواسطة معالج الفيديو الخاص بالكمبيوتر. يجب تجميع التظليل، الأمر الذي يستغرق وقتًا. لكن وحدة TEV لا تتمتع بالقدرة على حفظ التكوينات، لذا تقوم ألعاب GC/Wii بتكوينها لعرض التأثير ذات مرة، بمجرد الحاجة إليه، دون أي تأخير أو إخطارات. للتعامل مع هذا التناقض، يمكن لـ Dolphin فقط تأجيل تسلسل GPU بينما يقوم خيط GPU وبرنامج تشغيل الفيديو بالتجميع، مما يؤدي إلى الإيقاف المؤقت لوحدة تحكم GC/Wii التي تمت محاكاتها بشكل فعال. عادةً، يحدث التجميع بين الإطارات دون أن يلاحظ المستخدمون ذلك، ولكن إذا استمر لفترة أطول من الإطار، فستتوقف اللعبة مؤقتًا بشكل ملحوظ حتى اكتمال التجميع. هذا ما هو عليه تجميد عند تجميع التظليل. عادةً ما تستمر التأتأة في إطارين فقط، ولكن في المشاهد المزدحمة جدًا التي يتم فيها تجميع العديد من التظليل، يكون التلعثم ممكنًا لأكثر من ثانية.

حتى يتم إنشاء ذاكرة التخزين المؤقت للتظليل، تكون طريقة اللعب في Metroid Prime 3 مؤلمة للغاية (GIF).

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

حل مشكلة غير قابلة للحل

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

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

الحلول الممكنة

توليد كافة التظليل مقدما!



كمرجع، هناك حوالي 7.5 × 10 15 حبة رمل على الأرض.

يمكن لـ Dolphin إنشاء التظليلات التي يحتاجها بسرعة كبيرة، لكن المشكلة تكمن في التجميع. ولكن إذا تمكنا بطريقة ما من إنشاء وتجميع التظليلات لكل تكوين ممكن، فإن ذلك من شأنه أن يحل المشكلة، أليس كذلك؟ لسوء الحظ، هذا ببساطة مستحيل.

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

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

توقع التظليل الذي ستحتاجه اللعبة!


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

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

...وهو ما يقودنا إلى حل مقترح آخر.

تظليل عام


يستخدم Dolphin كائن معرف فريد ("UID") لوصف تكوين معالج الفيديو الذي تمت محاكاته. يتم تحويل معرفات UID هذه إلى رمز تظليل وتمريرها إلى برنامج تشغيل الفيديو لتجميعها. نظرًا لأنه تم تعيين UIDs قبل التجميع ولم يتم تخصيصها لأي معالج فيديو خاص بالكمبيوتر، فهي متوافقة مع أي كمبيوتر، ومن الناحية النظرية، يمكن مشاركتها. من الناحية النظرية، إذا شارك المستخدمون ملفات UID، فسيتمكنون من تجميع التظليل مسبقًا ولن يواجهوا أي تأخير. حاليًا في Vulkan API هناك بالفعل مثل هذا الاحتمال، وهو أمر ضروري لتجنب مشاكل التخزين المؤقت للتظليل في بعض برامج التشغيل.

فلماذا لم يتم تنفيذ هذا الحل أبدا؟

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

تجميع تظليل غير متزامن


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

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

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

قد يؤدي تخطي تجميع التظليل إلى ظهور الكائنات من الهواء الرقيق وظهور الرسومات مكسورة (GIF). لكن طريقة اللعب ظلت سلسة!

طرح المستخدمون السؤال: لماذا لم تقم شركة Dolphin بتضمين تظليل Tino غير المتزامن على الأقل كخيار لحل مشكلة التجميد عند تجميع التظليل. كل ذلك جاء إلى حقيقة أن الناس الذين استطاعتنفيذ هذه الميزة جنبًا إلى جنب مع المطورين الأساسيين الآخرين كانوا ضد هذا القرار. لقد رأوا ذلك مجرد اختراق من شأنه أن يؤدي إلى مجموعة من التقارير الإيجابية الكاذبة في أداة تعقب الأخطاء وحتى مشاكل أكبر في المستقبل. كانوا على حق في بعض النواحي: فقد أصبح من الواضح أن بعض الألعاب بحاجة لتقديم الكائنات في الإطار الذي من المتوقع أن تكون فيه. في هذه الحالة، تم عرض رؤوس الصورة الرمزية Mii مرة واحدة فقط في Embedded Framebuffer (EFB). إذا كانت نسخة من EFB مفقودة بسبب تجميع التظليل غير المتزامن، فلن تظهر رؤوس Mii حتى نهاية اللعبة أو حتى يتم تجديدها.


ميي مقطوعة الرأس

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

حل

اكتب مترجمًا لخط عرض GameCube/Wii داخل التظليل وقم بتشغيله في بطاقة الفيديو الخاصة بالكمبيوتر

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

ولكن ماذا لو لم نعتمد على التظليل المتخصص؟ لقد توصلنا إلى فكرة مجنونة - لتقليدها خط أنابيب العرض نفسهباستخدام مترجم يعمل مباشرة على معالج الفيديو مثل العديد من التظليل العالمي الضخم. إذا قمنا بتجميع هذه التظليلات الضخمة عند بدء اللعبة، فعندما تقوم اللعبة بتغيير تكوين Flipper/Hollywood لتقديم التأثيرات، ستكون "ubersshaders" هذه تكوين نفسكوتقديمها دون الحاجة إلى تظليلات جديدة. من الناحية النظرية، سيحل هذا مشكلة التجميد عند تجميع التظليل بفضل مكتملرفض التجميع.

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

إن ضمان الفوز يتطلب مئات، إن لم يكن الآلاف، من الساعات من العمل الرتيب والصعب، والمذهل للعقل.

تمت المحاولة الأولى في عام 2015، عندما كان أحد مطوري برامج Phire متعبًا للغاية من تجميد جهاز الكمبيوتر القوي الجديد الخاص به، لدرجة أنه قدم اقتراحًا وقام بتطوير إطار عمل لـ اوبرشادر. وعلى الرغم من أنه كان على دراية بجميع التعقيدات، إلا أنه بدا مصممًا على إثبات أن Ubershaders هو الحل لمشكلتنا القديمة. فير بنفسهحاولت إعادة تدريس تقديم دولفين.


هذا ليس مرشح الرسومات.


يبدو أن هناك بعض الأخطاء هنا...


بفضل بساطتها، كانت SM64 إحدى الألعاب الأولى التي تقدم شيئًا ما من خلال Ubershaders.

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


في البداية، قام Ubershaders بتحويل الألعاب إلى صور مشوهة للواقع.


لكن الوضع تحسن بسرعة.


قبل أن نتمكن من غمضة عين، كان Wind Waker قد تم عرضه بالفعل مع وجود أخطاء بسيطة فقط.



كان phire قادرًا على عرض Wind Waker بسرعة تامة. ولسوء الحظ، فإن الألعاب الأخرى التي تحتوي على قائمة أوسع من الميزات تتطلب الكثير من العمل.

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

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

اوبرشادر 2.0

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

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

حتى قبل أن ينضم Stenzek إلى Ubershaders، كان الفريق قد اتخذ قرارات بشأن دعم واجهات برمجة التطبيقات الرسومية. تلقى أحد القرارات، وهو التخلي عن D3D12 API، مراجعات مختلطة، إن لم تكن سلبية. على عكس حل D3D9، لم نرغب في الخضوع لعملية الإلغاء التدريجي وتخلصنا منه بمجرد أن أصبح من الواضح أنه لا أحد يريد دعم واجهة برمجة التطبيقات (API).

ولكن تبين أن هذا كان قرارًا جيدًا، لأن التخلص من واجهة برمجة التطبيقات (API) سمح بإحياء مشروع Ubershader عندما كان Stenzek جاهزًا له. لقد كان مهندس الواجهة الخلفية لـ Vulkan في Dolphin، لذلك أراد أن يبذل عملاً إضافيًا لجعل Ubershaders يعمل مع Vulkan.

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

كانت Metroid Prime 3 واحدة من الألعاب القليلة التي يؤدي فيها التلعثم في التظليل إلى تقليل التصنيف إلى غير قابل للعب. حتى وقت قريب (GIF)!

حقق الاختبار الأول لـ Ubershaders نجاحًا كبيرًا: اختفى التأتأة تمامًا في D3D، وفي OpenGL وVulkan لم يكن هناك سوى بعض التأتأة الغريبة في المراحل المبكرة. بينما نواصل العمل على Ubershaders، قمنا بتحسين كيفية عملهم بشكل كبير عبر جميع واجهات برمجة التطبيقات، مع بعض الاستثناءات التي سأغطيها لاحقًا. لكن مجرد تشغيل اللعبة على Ubershaders لم يكن كافيًا: فقد استهلكوا هم أنفسهم قدرًا كبيرًا من موارد بطاقة الفيديو الخاصة بالكمبيوتر. بالطبع، تختلف متطلبات الألعاب المختلفة، ولكن عادةً ما تتأثر بطاقة الفيديو بشكل كبير بالدقة التي تعمل بها اللعبة. يمكن لمعظم بطاقات الرسومات التعامل مع دقة 1x الأصلية (480 بكسل)، ويمكن للبطاقات الأكثر قوة التعامل مع دقة 1080 بكسل أو أعلى باستخدام Ubershaders فقط. لسوء الحظ، لم يكن لدى العديد من مستخدمينا الأجهزة اللازمة لتشغيل Ubershaders بالدقة التي اعتادوا عليها. لذلك كان عليهم الاختيار بين الدقة والنعومة.

بالكاد تستطيع معالجات الفيديو المدمجة من Intel التعامل مع تظليل Dolphin المتخصص بدقة عالية، ناهيك عن Ubershaders. (انقر على الصورة لعرض الإحصائيات.)

ش كبيرة جدًالدى بعض مستخدمي Dolphin معالجات فيديو مدمجة في أجهزة الكمبيوتر الخاصة بهم. عند اختبار معالجات الفيديو المدمجة، فإنها أفضل سيناريوتم تقديم ألعاب ثلاثية الأبعاد باستخدام Ubershaders بدقة 1x فقط 50% سرعة! أدرك المطورون أنه سيكون من الخطأ تجاهل جزء كبير من مستخدمي Dolphin وجعلوا Ubershaders اختياريًا. استمر العمل لإيجاد حل أكثر موثوقية يمكنه حل مشكلات الأداء مرة واحدة وإلى الأبد.

الوضع الهجين Ubershaders

وضع Hybrid Ubershader عبارة عن مزيج من Ubershaders وتوليد التظليل غير المتزامن في حل واحد جميل يأخذ أفضل ما في كل نهج، ولكنه يتخلص من عيوبه. نظرًا لأن الوضع الهجين يقلل بشكل كبير من استهلاك موارد Ubershader، فقد توقعنا أن يكون هذا هو وضع Ubershader الأكثر شيوعًا.

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

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

Ubershader API وDriver Shame Board

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

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

توليد متغيرات التظليل

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

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

حظر تظليل NVIDIA في OpenGL وVulkan

أبلغ بعض المستخدمين أن OpenGL وVulkan (في الوضع المختلط) لديهم تعثرات طفيفة عند تجميع التظليل. نحن لسنا متأكدين تمامًا مما يحدث لأن هذا لا يحدث في D3D، لكننا على يقين من أنه خطأ في برنامج تشغيل NVIDIA وليس خطأ في معالجة Dolphin. وفقًا لاختباراتنا، لا تتعلق هذه المشكلة بتوليد المتغير.

تعد التظليلات المجمعة من NVIDIA في OpenGL وVulkan أبطأ بكثير من D3D

وهذا أمر مزعج بشكل خاص لأنه ليس لدينا طريقة جيدة للتخلص من هذا الخطأ. نقوم بتمرير نفس التظليل إلى معالجات الفيديو باستخدام OpenGL وVulkan وD3D، ولكن اتضح أن D3D أسرع بكثيرتظليل العمليات. هذا يعني أنه على بطاقة GTX 760 مع OpenGL أو Vulkan يمكنك الحصول على دقة 1x، ولكن مع D3D يمكنك بسهولة مضاعفة هذه الدقة أو حتى ثلاثة أضعافها دون تقطع ملحوظ.

تحظر NVIDIA تفكيك التظليل، على الرغم من ذلك جميع الشركات المصنعة لمعالجات الفيديو الأخرىتوفير تظليل مفتوح مفكك. لذلك ليس لدينا طريقة لإصلاح هذا الخطأ أو فهم سبب كون التعليمات البرمجية المجمعة أكثر كفاءة في D3D. فكر في مدى روعة هذا الأمر: نريد أن يعمل Dolphin بشكل أسرع على بطاقات NVIDIA، لكن الشركة لا تقدم لنا الأدوات اللازمة للقيام بذلك. آمل أن تقوم الشركة بإزالة هذه العقبة في المستقبل. وبدون أدوات التفكيك التي توفرها الشركات المصنعة الأخرى، سيكون إصلاح الأخطاء أكثر صعوبة.

الشيء المحزن هو أن الأدوات التي نحتاجها متاحة - إذا كنت شركة ألعاب كبيرة بما يكفي. تصحيح: أبلغتنا NVIDIA أنها توفر فقط أدوات تفكيك التظليل لـ Direct3D 12 (مع اتفاقية عدم الإفصاح)، وأن هذه الأدوات غير متوفرة لواجهات برمجة التطبيقات الأخرى. نأمل أن تتوفر أدوات لواجهات برمجة التطبيقات الأخرى في المستقبل.

في برنامج تشغيل AMD لـ Vulkan ما زاللا يوجد دعم للتظليل المؤقت

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

لا تزال برامج تشغيل فيديو macOS فظيعة

كما هو الحال مع العديد من الميزات المثيرة، من المحتمل أن ينتظر مستخدمو macOS عبارة "لكن على macOS..." التي لا مفر منها. ها هي. لا تستطيع برامج تشغيل OpenGL 4.1 القديمة وغير الفعالة لنظام التشغيل macOS التعامل مع مهمة معالجة Ubershaders على أي مستوى مقبول. الوضع الهجين يقللالكبح، ولكن وضع Ubershaders وحده بطيء جدًا. وهناك عيب آخر: لا يزال نظام التشغيل macOS لا يدعم التخزين المؤقت للتظليل في أي من برامج التشغيل. نظرًا لكل مشكلات برامج التشغيل هذه، فليس من المستغرب أن تعمل بعض بطاقات الرسومات بشكل أفضل مع واجهات برمجة التطبيقات والإعدادات المحددة. لقد اخترنا شائعةالإعدادات الموصى بها لبطاقات الفيديو المختلفة. يمكنك اتباع هذه التوصيات وفقًا لتفضيلاتك وطراز بطاقة الفيديو. لا تنس أنه إذا قمت بتغيير بعض الإعدادات أثناء اللعبة، على سبيل المثال، الإضاءة لكل بكسل أو مستوى الصقل، فستحتاج إلى تجميع تظليلات جديدة، مما قد يتسبب في توقف مؤقت كبير. ضع في اعتبارك أيضًا أن Ubershaders يتطلب المزيد من طاقة وحدة معالجة الرسومات، مما يعني أنه مع نفس الإعدادات مطلوب بطاقة فيديو أكثر قوة.
  • شركة انتلالخامس شبابيك
    • في الوضع هجينيستخدم D3D. يعمل الوضع الحصري (الذي يستخدم Ubershaders فقط)، لكن بطاقات الرسومات المدمجة من Intel ليست قوية بما يكفي للتشغيل بأقصى سرعة حتى بدقة 1x الأصلية.
    • عندما يقوم السائق بإنشاء خيارات ل برنامج OpenGLيحدث التجميد.
    • سائق فولكانوهو يدعم معالجات Skylake فقط وهو أقوى، بالإضافة إلى أنه يحتوي على الكثير من الأخطاء ولا يستحق الاستخدام بعد.
  • شركة انتلالخامس لينكس
    • في الوضع هجينيستخدم فولكان. يعمل الوضع الحصري، ولكن ليس بأقصى سرعة.
    • من المرجح أن يتمكن برنامج تشغيل Anv الرائع من الاستفادة الكاملة من Ubershaders.
    • لا يقوم برنامج تشغيل الفيديو Intel i965 بتمرير تظليل OpenGL بين سلاسل العمليات. هذا يعني أن خيط العرض سيعيد دائمًا ترجمة التظليل، مما يؤدي إلى التلعثم. يعمل الوضع الحصري بشكل صحيح، على الرغم من أنه بطيء، ولكن في الوضع الهجين هناك تعثرات.


  • أيه إم ديالخامس شبابيك
    • في الوضع هجينيستخدم D3D.
    • في الوضع الحصرييستخدم D3Dأو فولكان.
    • سائق الشامل برنامج OpenGL AMD بطيء جدًا.
  • أيه إم ديالخامس لينكس
    • في وسائط حصريو هجينيستخدم فولكان.
    • يتصرف radv بشكل مشابه لـ anv ويعمل بشكل جيد.


انقر على الصورة لعرض التفاصيل
  • نفيدياالخامس شبابيك
    • في الوضع هجينيستخدم D3Dأو برنامج OpenGL.
    • في الوضع حصرييستخدم D3D, برنامج OpenGLأو فولكان. أوبرشادر D3Dعادةً ما تكون أكثر كفاءة من OpenGL وVulkan، مما يؤدي إلى أداء أفضل مع وحدات معالجة الرسومات الأضعف.
  • نفيدياالخامس لينكس
    • في الوضع هجينيستخدم برنامج OpenGL.
    • في الوضع حصرييستخدم برنامج OpenGLأو فولكان. قد تعتمد السرعة على واجهة برمجة التطبيقات (API) الموجودة في اللعبة بشكل أسرع. برجاء ملاحظة أن Vulkan يعاني من بعض التعثر عند إنشاء خيارات المسار، مما قد يتسبب في حدوث بعض التعثر البسيط في بداية اللعبة.
  • نفيدياالخامس ذكري المظهر
    • في الوضع هجينيستخدم برنامج OpenGL.
    • في الوضع حصرييستخدم برنامج OpenGLأو فولكان. في الوضع الحصري، يمكنك أيضًا الحصول على السرعة الكاملة على تلفزيون NVIDIA Shield في الألعاب البسيطة جدًا.


انقر على الصورة لعرض التفاصيل

باور في آرالخامس ذكري المظهر

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

أخيراً

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

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

ونظرًا لهذا المقال الضخم، لن يكون هناك تقرير مرحلي لشهر يوليو. نحن دعونا نتحدتغييرات يوليو رهيبة مع تقرير مرحلي لشهر أغسطس. سيكون كبيرًا، لذا ترقبوا!

وأقسم أنني بحثت كثيراً عن إجابة هذا السؤال، لكن لم أجد حلاً حقيقياً لمشكلتي. وما هي المشكلة؟

حسنًا، أنا جديد على DirectX والتظليل. هناك بعض الأشياء حول التظليل التي ما زلت لا أفهمها.

1-كيفية صنع التظليل؟ هل أحتاج إلى إنشاء ملف .fx في المشروع؟ في بعض الأحيان يكون هذا صحيحًا، لكن في بعض الأمثلة لا يمكنني العثور على الملف ‎.fx. وكيف يجب أن أفعل هذا الملف؟ لا يمكن لإصدار Visual Studio الخاص بي إنشاء ملفات .fx مباشرةً؛ أحتاج إلى "فرض" الملف ليكون .fx.

2- كيف أجمعها؟ هل يتم تجميعها في نفس وقت تجميع الحل أم أن لديها طرق تجميع خاصة؟

3 - هل يوجد برنامج تعليمي جيد؟ لقد بحثت عن كتاب مقدس للتظليل، لكن في الغالب وجدت برامج تعليمية غامضة وقصيرة تشرح بعض الأشياء ولم تكن متعمقة أبدًا.

2 إجابات

1. هل أنت جديد في شادر؟

للحصول على مقدمة حول شاردر، استخدم محرر Shazzam Shader المجاني (http://shazzam-tool.com/) لإنشاء تظليل بسيط باستخدام أدوات الرسم التفاعلية. حاول اللعب بخيار مختلف ثم قارن بين رموز HLSL التي تم إنشاؤها تلقائيًا (.fx) للحصول على فهم أفضل. بمجرد أن تشعر برغبة في كتابة كود التظليل، قم بشراء كتاب مدرسي قياسي/برنامج تعليمي عبر الإنترنت وتمرن على كتابة الكود الخاص بك وفقًا لمتطلباتك.

2. طرق التجميع العامة:

أ. D3DXCreateEffectFromFile -. قم بتسجيل كود التظليل واحفظ الامتداد .fx وقم بتجميع الكود ديناميكيًا D3DXCreateEffectFromFile. يمكن استخدام الكود المترجم في الوحدة الرئيسية الخاصة بك باستخدام واجهة التأثير (ID3DXEffect).

ب. تجميع صريح:. قم بتدوين رمز التظليل واحفظ الامتداد .fx وقم بتجميع الكود بشكل صريح باستخدام fxc.exe (يمكنك العثور عليه في مجلد DirectX SDK Utility).

مثال:
fxc.exe/Tfx_2_0/Fo file.fxo file.fx

بعد إنشاء الثنائي اتبع أدناه

1. قم بإنشاء مخزن مؤقت وقم بتحميل الملف الثنائي الذي تم إنشاؤه (.fxo) بواسطة دفق الملف. 2. اتصل بـ D3DXCreateEffect وقم بإعطاء محتوى المخزن المؤقت كمعلمة إدخال. 3. مثل "الطريقة أ" استخدم واجهة التأثير (ID3DXEffect) للتفاعل مع كود التظليل.

3. دليل الدراسة التمهيدية:

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

هناك طريقتان للقيام بذلك. يقوم أحدهم بوضع كود التظليل الخاص بك في ملفات .fx أو *.hlsl ثم يقوم بتجميع التظليل في وقت التشغيل باستخدام وظائف مكتبة D3D (D3DCompileFromFile). على الرغم من أن Microsoft لم تعد تقدم هذا لأن D3DCompileFromFile لن يعمل في تطبيقات نمط Metro. هناك طريقة أخرى وهي استخدام fxc.exe لتجميع التظليل الخاص بك في وقت الإنشاء. لقد جعل Visual Studio 2012 هذه العملية جزءًا من البنية العادية. بهذه الطريقة يمكنك إضافة ملفات hlsl الخاصة بك إلى مشروعك وسيتم إنشاؤها عند إنشاء مشروعك. سيسمح لك هذا أيضًا برؤية أي أخطاء/تحذيرات في التظليل في وقت الترجمة.

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

إنشاء ملفات شادر

يتم تخزين التظليل في ملفات منفصلة بامتداد .hsls. بالنسبة لهذا البرنامج التعليمي، أضفت ملفين إلى المشروع: PixelShader.hlsl وVertexShader.hlsl. يمكن إضافة ملف تظليل عبر عنصر القائمة Project → Add New Item، وفي النافذة التي تفتح، حدد نوع التظليل المطلوب:

تجميع التظليل

في DirectX 11 ضمن نظام التشغيل Windows 8، يمكن تجميع التظليل بثلاث طرق. اثنان منهم يستخدمان جهاز D3D11. الطريقة الثالثة هي وظيفة D3DCompileFromFile، وهي خاصة بـ HLSL. هذه هي الوظيفة التي سنستخدمها لتجميع التظليل. إنها ببساطة الطريقة الأسرع والأسهل.

لاحظ أن الوثائق تشير إلى أنه لا يمكن وضع التطبيقات التي تستخدم D3DCompileFromFile في متجر Windows.

لاستخدام مترجم التظليل، تحتاج إلى تضمين ملف الرأس D3DCompiler.h ومكتبة d3dcompiler.lib:

1?#تشمل #pragma comment(lib,"D3dcompiler.lib") ?1!

وظيفة D3DCompileFromFile

تقوم الدالة D3DCompileFromFile بتجميع تظليل HLSL. يأخذ ملفًا يحتوي على كود مصدر التظليل ويعيد (الوسيطة قبل الأخيرة) مثيلًا لواجهة ID3DBlob (blob هو اختصار لـ Binary Large Object، أي أنه مجرد مجموعة كبيرة من البيانات):

1?HRESULT WINAPI D3DCompileFromFile(LPCWSTR pFileName, const D3D_SHADER_MACRO *pDefines, ID3DInclude *pInclude, LPCSTR pEntrypoint, LPCSTR pTarget, UINT Flags1, UINT Flags2, ID3DBlob **ppCode, ID3DBlob **ppErrorMsgs);?1!

1. pFileName - اسم الملف الذي يحتوي على كود مصدر التظليل.

2. pDefines - مجموعة من وحدات الماكرو للتظليل. في الوقت الحالي، نمرر NULL فقط.

3.pInclude - يتم تعيين هذه الوسيطة عندما يكون التوجيه #include موجودًا في ملف التظليل. اضبطه على NULL.

4.pEntrypoint - نقطة دخول التظليل، أي. اسم الوظيفة مع رمز التظليل. بشكل افتراضي، يستخدم Visual Studio الملف الرئيسي.

5.pTarget - إصدار التظليل ونوعه: الحساب، المجال، الهندسة، الهيكل، البكسل، الرأس. في الوقت الحالي، نحتاج إلى العنصرين الأخيرين: البكسل والقمة. في DirectX 11، تحتاج إلى استخدام الإصدار 5 من التظليل. نقوم بتمرير القيم: vs_5_0 - قمة الرأس، ps_5_0 - بكسل.

6-7. أعلام. الآن نترك NULL.

8. مثيل ID3DBlob حيث سيتم حفظ التظليل المترجم.

9. ppErrorMsgs - سيتم حفظ رسائل الخطأ هنا. نحن نمر فارغة.

لذلك دعونا نجمع تظليل الرأس والبكسل:

1?ID3DBlob* vsBlob; ID3DBlob* psBlob; D3DCompileFromFile(L"VertexShader.hlsl"، NULL، NULL، "main"، "vs_5_0"، NULL، NULL، &vsBlob، NULL); D3DCompileFromFile(L"PixelShader.hlsl"، NULL، NULL، "main"، "ps_5_0"، NULL، NULL، &psBlob، NULL)؛؟1!

نقوم بتجميع تظليل قمة الرأس في vsBlob، وتظليل البكسل في psBlob.

إنشاء كائنات تظليل في DirectX 11

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

1?HRESULT CreateVertexShader(const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11VertexShader **ppVertexShader);?1!

1. pShaderBytecode - عنوان التظليل المترجم في الذاكرة.

2. BytecodeLength - حجم التظليل المترجم.

تحتوي واجهة ID3DBlob على طريقتين لتخزين القيمتين السابقتين: GetBufferPointer - عنوان التظليل المترجم، GetBufferSize - الحجم. هذه الأساليب لا تأخذ أي حجج.

3. pClassLinkage - يتم استخدام الوسيطة للارتباط الديناميكي. اضبطه على NULL.

4. ppVertexShader - سيتم حفظ كائن التظليل الذي تم إنشاؤه في هذا المتغير.

دعونا نلقي نظرة على الكود:

1?ID3D11VertexShader* مقابل; ID3D11PixelShader* ملاحظة؛ dev->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), NULL, &vs); dev->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), NULL, &ps);?1!

كل ما تبقى هو تنشيط التظليل الذي تم إنشاؤه:

1?devContext->VSSetShader(vs, NULL, NULL); devContext->PSSetShader(ps, NULL, NULL);?1!

هنا يقوم سياق الجهاز بتعيين تظليل الرأس والبكسل الحالي. الوسيطتين الثانية والثالثة ليست مهمة في هذه المرحلة.

خاتمة

في المشروع المرفق، يستخدم التظليل التعليمات البرمجية التي تم إنشاؤها بواسطة Visual Studio بشكل افتراضي. لا تفعل تظليلات البكسل والقمة هذه شيئًا مع البيانات. عند تشغيل البرنامج، لن ترى أي اختلافات. تأكد (في مصحح الأخطاء) من أن vsBlob وpsBlob وvs وps لها عناوين حقيقية (وليس صفرًا).

في هذا البرنامج التعليمي، تعلمنا كيفية تكوين مرحلتين مهمتين من مسار رسومات DirectX 11: تظليل الرأس والبكسل. الآن كل ما يتعين علينا القيام به هو تزويد خط الرسومات بالبيانات.

عندما أقوم بتجميع تظليل، هل يجب أن يكون ممتلئًا؟ هل يمكنني استخدام glCompileShader على تظليل بدون وظيفة main()؟ تحتوي الوثائق المرجعية لـ OpenGL على إدخال خطأ جيد لربط البرنامج، لكن لا يمكنني العثور على واحد لربط التظليل، لذا يجب أن أسأل هنا.

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

0

2 إجابات

تم وصف نموذج التجميع لـ OpenGL في Wiki. ولكن بالنسبة لاحتياجاتك، أود أن أقترح عليك فقط استخدام حقيقة أنه يقبل خطوطًا متعددة. تعمل هذه الخطوط بشكل فعال كملفات رأسية؛ يقوم التظليل ببنائها معًا وتجميعها كوحدة واحدة.

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