المقدمة
في هذه السلسلة من المنشورات ، سنغطي نقل Detroit: Become Human من PlayStation 4 إلى الكمبيوتر الشخصي. تم إصدار
Detroit: Become Human على PlayStation 4 في مايو 2018. بدأنا العمل على إصدار الكمبيوتر الشخصي في يوليو 2018 وأصدرناه في ديسمبر 2019. هذه لعبة مغامرة بها ثلاث شخصيات قابلة للعب والعديد من الوقائع المنظورة. تحتوي على رسومات عالية الجودة وقد تم تطوير معظم تقنيات الرسومات بواسطة Quantic Dream نفسها.
يتميز المحرك ثلاثي الأبعاد بخصائص ممتازة:
- عرض واقعي للشخصيات.
- إضاءة PBR.
- جودة ما بعد المعالجة مثل عمق المجال (DOF) وضبابية الحركة وما إلى ذلك.
- صقل مؤقت.

Detroit: Become Human
منذ البداية ، تم تصميم محرك اللعبة ثلاثي الأبعاد خصيصًا لجهاز PlayStation ، ولم يكن لدينا أي فكرة أنه سيدعم لاحقًا منصات أخرى. لذلك ، كان إصدار الكمبيوتر الشخصي يمثل تحديًا لنا.
- 3D محرك الرصاص رونان Marshalot ومحرك 3D يؤدي نيكولاس Viseri و جوناثان سيرت من كوانتيك دريم سوف نتحدث عن الجوانب مما يجعل من اللعبة استدار. سيشرحون التحسينات التي يمكن نقلها بسهولة من PlayStation 4 إلى الكمبيوتر الشخصي ، والصعوبات التي واجهوها بسبب الاختلافات بين المنصات.
- Lou Kramer هو مهندس تطوير تقني في AMD . لقد ساعدتنا في تحسين اللعبة ، لذلك ستتحدث بالتفصيل عن فهرسة الموارد غير الموحدة على الكمبيوتر الشخصي ، وعلى وجه الخصوص ، في بطاقات AMD.
اختيار واجهة برمجة تطبيقات الرسومات
لدينا بالفعل إصدار OpenGL من المحرك ، والذي استخدمناه في أدوات التطوير الخاصة بنا.
لكننا لم نرغب في إصدار اللعبة في OpenGL:
- كان لدينا الكثير من الامتدادات الخاصة التي لم تكن مفتوحة لجميع مصنعي GPU.
- كان أداء المحرك منخفضًا جدًا في OpenGL ، على الرغم من إمكانية تحسينه بالطبع.
- في OpenGL ، هناك العديد من الطرق لتنفيذ جوانب مختلفة ، لذلك كان تنفيذ جوانب مختلفة بشكل صحيح على جميع المنصات بمثابة كابوس.
- OpenGL . , , .
نظرًا للاستخدام المكثف للموارد غير ذات الصلة ، لم نتمكن من نقل اللعبة إلى DirectX11. لا تحتوي على فتحات موارد كافية ، وسيكون من الصعب جدًا تحقيق أداء لائق إذا كان علينا إعادة التظليل لاستخدام موارد أقل.
كنا نختار بين DirectX 12 و Vulkan ، اللتين لهما مجموعة ميزات متشابهة جدًا. سيمكننا Vulkan بشكل أكبر من توفير الدعم لنظام Linux والهواتف المحمولة ، وسيوفر DirectX 12 الدعم لـ Microsoft Xbox. كنا نعلم أننا في النهاية سنحتاج إلى تنفيذ دعم لكل من واجهات برمجة التطبيقات ، ولكن سيكون من المنطقي أن يركز المنفذ على واجهة برمجة تطبيقات واحدة فقط.
يدعم Vulkan نظامي التشغيل Windows 7 و Windows 8. نظرًا لأننا أردنا أن نجعل ديترويت: كن إنسانًافي متناول أكبر عدد ممكن من اللاعبين ، أصبحت هذه حجة قوية للغاية. ومع ذلك ، فقد استغرق النقل عامًا واحدًا ، وهذه الحجة غير مهمة بالفعل ، لأن نظام التشغيل Windows 10 يستخدم الآن على نطاق واسع!
مفاهيم واجهة برمجة تطبيقات الرسومات المختلفة
تحتوي إصدارات OpenGL والإصدارات الأقدم من DirectX على نموذج تحكم GPU بسيط للغاية. هذه واجهات برمجة التطبيقات سهلة الفهم ومناسبة جدًا للتعلم. يوجهون السائق للقيام بالكثير من العمل المخفي عن المطور. لذلك ، سيكون من الصعب جدًا تحسين محرك ثلاثي الأبعاد يعمل بكامل طاقته فيها.
من ناحية أخرى ، فإن PlayStation 4 API خفيف الوزن للغاية وقريب جدًا من الأجهزة.
يقع Vulkan في مكان ما بينهما. كما أن لديها أفكارًا تجريدية لأنها تعمل على وحدات معالجة رسومات مختلفة ، لكن المطورين لديهم المزيد من التحكم. لنفترض أن لدينا مهمة لتنفيذ إدارة الذاكرة أو ذاكرة التخزين المؤقت للتظليل. نظرًا لوجود عمل أقل للسائق ، يتعين علينا القيام بذلك! ومع ذلك ، قمنا بتطوير مشاريع على PlayStation ، وبالتالي يكون من الملائم لنا أن نتحكم في كل شيء.
الصعوبات
وحدة المعالجة المركزية PlayStation 4 هي AMD Jaguar ذات 8 أنوية. من الواضح أنه أبطأ من أحدث أجهزة الكمبيوتر ؛ ومع ذلك ، يتمتع PlayStation 4 بمزايا مهمة ، على وجه الخصوص ، الوصول السريع جدًا إلى الأجهزة. نعتقد أن واجهة برمجة تطبيقات رسومات PlayStation 4 أكثر كفاءة بكثير من جميع واجهات برمجة التطبيقات على جهاز الكمبيوتر. إنه مباشر للغاية ولا يهدر موارد قليلة. هذا يعني أنه يمكننا تحقيق عدد كبير من استدعاءات السحب لكل إطار. لقد علمنا أن المكالمات عالية السحب يمكن أن تكون مشكلة على أجهزة الكمبيوتر الأبطأ.
ميزة أخرى مهمة هي أنه يمكن تجميع جميع أدوات التظليل على PlayStation 4 مسبقًا ، مما يعني أنه تم تحميلها على الفور تقريبًا. على الكمبيوتر الشخصي ، يجب على برنامج التشغيل تجميع تظليل في وقت التمهيد: نظرًا للعدد الكبير من تكوينات GPU وبرامج التشغيل المدعومة ، لا يمكن إجراء هذه العملية مسبقًا.
أثناء تطوير لعبة Detroit: Become Human على PlayStation 4 ، تمكن الفنانون من إنشاء أشجار تظليل فريدة لجميع المواد. أنتج هذا قدرًا مجنونًا من الرؤوس وتظليل البكسل ، لذلك عرفنا منذ بداية المنفذ أن هذه ستكون مشكلة كبيرة.
خطوط أنابيب شادر
كما نعلم من محرك OpenGL الخاص بنا ، يمكن أن يستغرق تجميع المظلات وقتًا طويلاً على جهاز الكمبيوتر. أثناء إنتاج اللعبة ، أنشأنا ذاكرة تخزين مؤقت تظليل استنادًا إلى نموذج وحدة معالجة الرسومات لمحطات العمل الخاصة بنا. إنشاء مخبأ تظليل كامل لديترويت: استغرق برنامج Become Human ليلة كاملة! تمكن جميع الموظفين من الوصول إلى ذاكرة التخزين المؤقت هذه في الصباح. لكن اللعبة لا تزال تتباطأ ، لأن السائق كان بحاجة إلى تحويل هذا الرمز إلى رمز المجمع الأصلي لتظليل GPU.
اتضح أن Vulkan يتعامل مع هذه المشكلة بشكل أفضل بكثير من OpenGL.
أولاً ، لا يستخدم Vulkan لغة تظليل عالية المستوى مثل HLSL ، ولكنه يستخدم بدلاً من ذلك لغة تظليل وسيطة تسمى SPIR-V. يعمل SPIR-V على تسريع تجميع التظليل ويجعل من السهل التحسين لمترجم تظليل السائق. في الواقع ، من حيث الأداء ، يمكن مقارنته بنظام التخزين المؤقت OpenGL shader.
في Vulkan ، يجب ربط التظليل بالشكل
VkPipeline. على سبيل المثال ، VkPipelineيمكنك إنشاء من قمة وتظليل بكسل. يحتوي أيضًا على معلومات حالة العرض (اختبارات العمق ، والاستنسل ، والمزج ، وما إلى ذلك) وتقديم تنسيقات الهدف. هذه المعلومات مهمة للسائق حتى يتمكن من تجميع الظلال بأكبر قدر ممكن من الكفاءة.
في OpenGL ، لا يعرف تجميع التظليل سياق استخدام التظليل. يحتاج السائق إلى انتظار مكالمة سحب لإنشاء ثنائي GPU ، وهذا هو السبب في أن مكالمة السحب الأولى باستخدام تظليل جديد يمكن أن تستغرق وقتًا طويلاً على وحدة المعالجة المركزية.
في Vulkan ،
VkPipelineيوفر خط الأنابيب سياقًا للاستخدام ، بحيث يكون لدى السائق كل المعلومات التي يحتاجها لإنشاء ثنائي GPU ، ولا يضيع استدعاء السحب الأول أي موارد. أيضا ، يمكننا تحديث VkPipelineCacheالخلق VkPipeline.
في البداية ، حاولنا إنشاء
VkPipelinesأول مرة نحتاجها. تسبب هذا في تباطؤ مماثل للوضع مع برامج تشغيل OpenGL. ثم تم VkPipelineCacheتحديثه واختفت الكبح حتى مكالمة السحب التالية.
ثم توقعنا أننا سنكون قادرين على الإنشاء
VkPipelinesفي وقت التمهيد ، ولكن عندما VkPipelineCacheكان الأمر غير ذي صلة ، كان بطيئًا جدًا بحيث لا يمكن تنفيذ استراتيجية التحميل في الخلفية.
في النهاية ، قررنا إنشاء كل شيء
VkPipelineأثناء الإطلاق الأول للعبة. أدى هذا إلى القضاء على مشاكل الكبح تمامًا ، لكننا الآن نواجه صعوبة جديدة: VkPipelineCacheاستغرق الجيل وقتًا طويلاً جدًا.
ديترويت: كن إنسانًا يحتوي على ما يقرب من 99500
VkPipeline! تستخدم اللعبة التقديم الأمامي ، لذا فإن تظليل المواد يحتوي على كل كود الإضاءة. لذلك ، يمكن أن يستغرق تجميع كل تظليل وقتًا طويلاً.
توصلنا إلى عدة أفكار لتحسين العملية:
- , SPIR-V.
- SPIR-V SPIR-V.
- , CPU 100%
VkPipeline.
أيضًا ، تم اقتراح تحسين مهم بواسطة Jeff Boltz من NVIDIA ، وفي حالتنا تبين أنه فعال للغاية.
كثير
VkPipelineمتشابه جدا. على سبيل المثال ، VkPipelineقد يكون لبعضها نفس الرؤوس وتظليل البكسل ، وتختلف فقط في حالات تجسيد قليلة ، مثل معاملات الاستنسل. في هذه الحالة ، يمكن للسائق معاملتها كخط أنابيب واحد. ولكن إذا قمنا بإنشائها في نفس الوقت ، فسيكون أحد الخيوط خاملاً ببساطة ، في انتظار الآخر لإكمال المهمة. بطبيعتها ، نقلت عمليتنا جميع العمليات المتشابهة VkPipelineفي نفس الوقت. لحل هذه المشكلة ، قمنا بتغيير ترتيب الفرز VkPipeline. تم وضع "الحيوانات المستنسخة" في النهاية ، ونتيجة لذلك ، بدأ إنشاءها يستغرق وقتًا أقل بكثير.
أداء الخلق
VkPipelinesيختلف كثيرا. على وجه الخصوص ، يعتمد بشكل كبير على عدد مؤشرات ترابط الأجهزة المتاحة. على AMD Ryzen Threadripper مع 64 خيطًا للأجهزة ، يمكن أن يستغرق الأمر أقل من دقيقتين. لسوء الحظ ، قد تستغرق هذه العملية أكثر من 20 دقيقة على أجهزة الكمبيوتر الشخصية الضعيفة.
كانت الأخيرة طويلة جدًا بالنسبة لنا. لسوء الحظ ، كانت الطريقة الوحيدة لتقليل هذا الوقت هي تقليل عدد التظليل. سنحتاج إلى تغيير طريقة إنشاء المواد بحيث تتم مشاركة أكبر عدد ممكن منها. بالنسبة إلى Detroit: Become Human ، كان هذا مستحيلًا ، لأن الفنانين سيضطرون إلى إعادة كل المواد. نحن نخطط لتنفيذ التثبيت المادي المناسب في اللعبة التالية ، ولكن بعد فوات الأوان بالنسبة إلى ديترويت: كن إنسانًا .
واصفات الفهرسة
لتحسين سرعة مكالمات السحب على جهاز الكمبيوتر ، استخدمنا فهرسة الواصفات باستخدام الامتداد
VK_EXT_descriptor_indexing. مبدأها بسيط: يمكننا إنشاء مجموعة من الواصفات تحتوي على جميع المخازن المؤقتة والأنسجة المستخدمة في الإطار. ثم يمكننا الوصول إلى المخازن المؤقتة والقوام من خلال الفهارس. الميزة الرئيسية لهذا هو أن الموارد مرتبطة مرة واحدة فقط لكل إطار ، حتى لو تم استخدامها في مكالمات سحب متعددة. هذا مشابه جدًا لاستخدام موارد غير منضمة في OpenGL.
نقوم بإنشاء مصفوفات الموارد لجميع أنواع الموارد المستخدمة:
- مجموعة واحدة لجميع القوام ثنائي الأبعاد.
- مجموعة واحدة لجميع الزخارف ثلاثية الأبعاد.
- مصفوفة واحدة لجميع الزخارف المكعبة.
- مجموعة واحدة لجميع المخازن المؤقتة للمواد.
لدينا فقط المخزن المؤقت الرئيسي الذي يتغير بين مكالمات السحب (يتم تنفيذه كمخزن مؤقت دائري) يحتوي على فهرس واصف يشير إلى المخزن المؤقت للمادة المطلوبة والمصفوفات المطلوبة. يحتوي كل مخزن مواد على مؤشرات عن القوام المستخدم

بفضل هذه الإستراتيجية ، تمكنا من الاحتفاظ بعدد صغير من مجموعات الواصف المشتركة لجميع مكالمات السحب وتحتوي على جميع المعلومات اللازمة لرسم الإطار.
تحسين تحديثات مجموعة الواصف
حتى مع وجود عدد صغير من مجموعات الواصفات ، كان تحديثها لا يزال يمثل عنق الزجاجة. قد يكون تحديث مجموعة واصفات مكلفًا للغاية إذا كان يحتوي على العديد من الموارد. على سبيل المثال ، في إطار واحد من Detroit: Become Human ، يمكن أن يكون هناك أكثر من أربعة آلاف مادة.
لقد قمنا بتنفيذ تحديثات تدريجية لمجموعات الواصف ، مع تتبع الموارد التي أصبحت مرئية وغير مرئية في الإطار الحالي. بالإضافة إلى ذلك ، فإنه يحد من حجم مصفوفات الواصف ، لأن لديهم سعة كافية للتعامل مع الموارد المرئية في الوقت الحالي. يؤدي تتبع الرؤية إلى إهدار القليل من الموارد لأننا لا نستخدم خوارزمية مكلفة لحساب التقاطعات
O(n.log(n))... بدلاً من ذلك ، نستخدم قائمتين ، واحدة للإطار الحالي والأخرى للإطار السابق. يساعد نقل الموارد المرئية المتبقية من قائمة إلى أخرى وفحص الموارد المتبقية في القائمة الأولى على تحديد الموارد التي تدخل وتختفي من الهرم.
يتم تخزين دلتا التي تم الحصول عليها خلال هذه الحسابات لأربعة إطارات - نستخدم التخزين المؤقت الثلاثي ، ولحساب متجهات حركة الكائنات ذات الجلد ، يلزم إطار واحد آخر. يجب أن تظل مجموعة الواصف بدون تغيير لأربعة إطارات على الأقل قبل أن تتمكن من تعديلها مرة أخرى ، لأنها يمكن أن تظل مفيدة لوحدة معالجة الرسومات. لذلك ، نقوم بتطبيق دلتا على مجموعات من أربعة إطارات.
في النهاية ، أدى هذا التحسين إلى تقليل وقت التحديث لمجموعات الواصف بمقدار واحد إلى اثنين من حيث الحجم.
ذبح الأعداء
يسمح لنا استخدام فهرسة الواصف بتجميع مجموعات بدائية متعددة في مكالمة سحب واحدة باستخدام
vkCmdDrawIndexedIndirect. نستخدم gl_InstanceIDللوصول إلى الفهارس المرغوبة في المخزن المؤقت الرئيسي. يمكن تجميع العناصر الأولية في دفعات إذا كان لديهم نفس مجموعة الواصفات ونفس خط أنابيب التظليل ونفس المخزن المؤقت للرأس. هذا فعال للغاية ، خاصة أثناء تمريرات العمق والظل. تم تقليل إجمالي عدد مكالمات السحب بنسبة 60٪.
بهذا يختتم الجزء الأول من سلسلة المقالات. في الجزء الثاني ، سيتحدث مهندس التكنولوجيا Lou Kramer عن فهرسة الموارد غير المتجانسة على أجهزة الكمبيوتر وبطاقات AMD على وجه الخصوص.