شرح تطوير نظام عرض رسومي مخصص يعتمد على بيانات الرؤوس مباشرة لتحسين الأداء في لعبة Planet Smith.
Key Takeaways
- العرض المباشر من بيانات الرؤوس يمكن أن يسرع الأداء بشكل كبير.
- استخدام العرض غير المباشر وتقنيات تقليم المنظور هي مفتاح تحسين الأداء في الألعاب الكبيرة.
- تقسيم الشبكة الضخمة إلى شبكات أصغر يقلل من نوبات البطء ويزيد من الكفاءة.
- تبسيط البيانات وتقليل حجمها ضروري لتحقيق أداء عالٍ في أنظمة العرض المعقدة.
- التقنيات المطورة تدعم عرض قطع فريدة غير قابلة للنسخ، مما يناسب الألعاب ذات العوالم المفتوحة.
What the video covers
- تم استبدال نظام الفيزياء المعتمد على الشبكات بنظام يعتمد على وحدات الفوكسل.
- تم استكشاف إمكانية عرض الرسوميات مباشرة من بيانات الرؤوس والمؤشرات دون الحاجة إلى إنشاء شبكة تقليدية.
- تم تطوير تقنية العرض غير المباشر (indirect rendering) باستخدام شبكة ضخمة قابلة للتعديل.
- تم استخدام تقنيات مثل تقليم المنظور (Frustum culling) وهيكل الشجرة الثمانية (octree) لتحسين الأداء.
- تم تقسيم الشبكة الضخمة إلى شبكات أصغر عبر خاصية الترحيل (Paging) لتقليل نوبات البطء.
- تم تطبيق تقنيات تبسيط الشبكات مثل الشبكة الجشعة (Greedy Meshing) لمواجهة تحديات السطوح المنحنية.
- تم تحسين حجم البيانات المخزنة للرؤوس والنواظم لتقليل استهلاك الذاكرة.
- تم تحقيق زيادة كبيرة في الأداء مع الوصول إلى أكثر من 170 إطاراً في الثانية مقارنة بخط الأساس.
- التقنيات المطورة تسمح بعرض قطع فريدة غير قابلة للنسخ (non-instanced chunks).
- التطوير مستمر مع خطط لتحسينات إضافية لتجاوز حاجز 200 إطار في الثانية.
Chapters
- 00:00مقدمة وتغيير نظام الفيزياء إلى الفوكسل
- 01:17مراجعة طريقة العرض الحالية وأهداف التحسين
- 02:37تجربة دمج القطع في شبكة ضخمة واحدة
- 05:20تطبيق العرض غير المباشر وتقنيات المخازن المؤقتة
- 06:28التأكيد على عدم استخدام النسخ (instancing)
- 07:19إضافة تقليم المنظور لتحسين الأداء
- 08:31استخدام هيكل الشجرة الثمانية لتسريع التقليم
- 09:36مشكلة حجم الشبكة الضخمة وحل الترحيل
- 11:40خطط لتبسيط الشبكات وتحسين الأداء المستقبلي
- 12:26مناقشة حجم البيانات وتحسين التخزين
Full Transcript — Download SRT & Markdown
Speaker A
في سجل التطوير السابق، قمنا بإزالة اعتماد محرك الفيزياء لدينا على الشبكات بالكامل. استبدلناه بنظام مخصص يعتمد على وحدات الفوكسل. بنينا تصادم الفيزياء مباشرة من بيانات الفوكسل بدلاً من شبكات الفيزياء.
Speaker A
وهذا دفعني للتفكير. ماذا لو تخلصنا من الشبكات في العرض أيضاً؟ هل هذا ممكن أصلاً؟ لأن الأمر هو أن كل لعبة تقريباً تعمل بنفس الطريقة عندما يتعلق الأمر بالعرض. يقوم فنان بصنع شبكة في برنامج بلندر أو مايا. تتم استيراد تلك الشبكة
Speaker A
إلى المحرك. ويقوم المحرك بعرضها. المثلثات، والإحداثيات، وسير العمل بالكامل هو الطريقة المعتادة للقيام بذلك. وبشكل طبيعي كنت أستخدم نفس ذلك الإطار. استخدام بيانات الفوكسل لإنشاء بيانات الرؤوس والمثلثات. تحويل تلك البيانات إلى شبكة. ثم تعيين تلك الشبكة لكائن، وأخيراً عرض
Speaker A
تلك الشبكة. لكن، ماذا لو تخطينا الشبكة تماماً وعرضنا مباشرة من بيانات الرؤوس؟ إذا كان ذلك ممكناً، فسيؤدي إلى تبسيط سير عملنا بالكامل ومنحنا دفعة كبيرة في الأداء.
Speaker A
حرق للأحداث: يمكننا ذلك. مرحباً، لا تنسوا إضافة لعبة Planet Smith إلى قائمة أمنياتكم على Steam والاشتراك هنا على يوتيوب. إنها أفضل طريقة لدعم تطوير اللعبة. إذاً، هذه هي الطريقة التي تعمل بها اللعبة حالياً. يتم تمييز الأجزاء المتغيرة لتحديثها.
Speaker A
نظام تحديث الأجزاء الخاص بي يقرأ ذلك الجزء المتغير وينشئ قائمة جديدة من الرؤوس والمؤشرات. يتم بعد ذلك تحميل تلك الرؤوس والمؤشرات في نظام إنشاء الشبكة الخاص بي، الذي يحول تلك البيانات إلى شبكة تقليدية مع عمليات حسابية إضافية أثناء
Speaker A
ذلك، مثل حساب ناقل كل وجه ومربع حدود الشبكة للعرض. يتم بعد ذلك تعيين الشبكة لكائن لعبة يحتوي على المواد اللازمة للعرض.
Speaker A
وأخيراً، بعد كل هذا العمل، يظهر للاعب شبكة معروضة على شاشته. هذا يعمل، لكنه بطيء.
Speaker A
وتبدو خطوة إنشاء الشبكة بأكملها مجهوداً ضائعاً. بطاقة الرسوميات الخاصة بك لا تحتاج إلى الشبكة ككائن لعرضها. هذه فقط هي الطريقة التي اعتدنا جميعاً على العمل بها مع محركات الألعاب. نظرياً، يجب أن نكون قادرين على أخذ بيانات الرؤوس والمؤشرات الخاصة بنا
Speaker A
وعرضها مباشرة، مما يلغي نظامين كاملين ويبسط العملية برمتها. كما أن لديها ميزة كبيرة أخرى، من الناحية النظرية. إذا تحكمنا في العرض بشكل أدق، يمكننا جعل مادة تضاريس اللعبة تعرض كل شيء في تمريرة عرض واحدة، بدلاً من الطريقة الحالية التي
Speaker A
تستخدم تمريرة عرض واحدة لكل جزء. في الرسوميات، يكون من الأسرع دائماً الحصول على عدد أقل من تمريرات العرض الكبيرة بدلاً من الكثير من التمريرات الصغيرة. قبل أن نبدأ، دعونا نسجل خط أساس للأداء الحالي عند مسافة رسم 40 جزءاً.
Speaker A
تعاني اللعبة حالياً وأحصل على حوالي 25 إلى 40 إطاراً في الثانية مع انخفاضات تصل إلى 10 إطارات. يبدو هذا كنقطة بداية جيدة.
Speaker A
فكرتي الأولى كانت دمج كل قطعة في شبكة ضخمة واحدة. هذا يعني أننا لا نزال بحاجة لإنشاء شبكة، لكنها على الأقل شبكة واحدة نتابعها الآن. ومع ذلك، فإن إعادة إنشاء هذه الشبكة الضخمة عند تغيير كتلة واحدة يقضي تماماً على أي مكاسب
Speaker A
في الأداء. ما نحتاجه بدلاً من ذلك هو شبكة ضخمة قابلة للتعديل، وليست قابلة لإعادة الكتابة. هنا يأتي دور العرض غير المباشر (indirect rendering). إنه يتيح لنا الحصول على أفضل ما في العالمين. شبكة ضخمة واحدة للأداء، ولكن مقسمة إلى شبكات
Speaker A
أصغر عبر أوامر الرسم. إليك كيف يعمل الأمر. أولاً، نقوم بتخصيص بعض الذاكرة على وحدة معالجة الرسومات لشبكتنا الضخمة. مخزن مؤقت للرؤوس، ومخزن مؤقت للفهارس. مخزن مؤقت لفهارس النسخ الخاصة بنا. هذا يربط بيانات الرؤوس لدينا ببيانات النسخ. ثم نستخدم العديد من
Speaker A
المخازن المؤقتة حسب حاجتنا لبيانات النسخ. أشياء مثل مصفوفة التحويل، وبيانات الاستدعاء مثل مربع الحدود والوسائط المفهرسة غير المباشرة المطلوبة للعرض الفعلي. بعد ذلك نأخذ أي بيانات شبكة تم إنشاؤها، ونبحث عن مساحة فارغة في مخازننا ونملؤها ببيانات الشبكة. كأنها
Speaker A
شبكة ضخمة واحدة، لكن لا يجب أن تكون كتلة متصلة واحدة. يمكننا ترك فجوات وإضافة أو إزالة أقسام كاملة دون الإضرار بالهيكل. ثم نقوم بعرض كل شيء باستخدام الرسوميات.
Speaker A
عرض العناصر البدائية بشكل مفهرس غير مباشر. بدلاً من عرض كل شبكة من هذه الشبكات على حدة، نستخدم مخزن الوسائط لبناء قائمة من أوامر الرسم، واحدة لكل جزء نريد رسمه.
Speaker A
يمكننا الحصول على الكثير من الأوامر المنفصلة، أمر لكل شبكة، لكن هذا هو الجزء الأساسي. بمجرد أن نبدأ، تتم معالجة كل تلك الأوامر دفعة واحدة على وحدة معالجة الرسومات كما لو كانت شبكة ضخمة واحدة بالفعل. هذا معقد بالطبع، لذا بدأت على
Speaker A
نطاق صغير بعرض 10,000 مربع متغير باستمرار يتم تحديثها كل بضعة إطارات. لو كنت أعامل كل مربع كشبكة منفصلة وأعرضه بتلك الطريقة، لكانت النتيجة عرض شرائح بطيئاً. بدلاً من ذلك، يعمل الأمر بسلاسة. إثبات أن التقنية تعمل بالفعل.
Speaker A
الآن، يجب أن أؤكد أن هذه المربعات ليست نسخاً (instances). كل واحد منها هو شبكة فريدة خاصة به. استخدام النسخ (instancing) سيعمل بشكل جيد في هذا المثال البسيط، لكن ليس هذا هو الهدف.
Speaker A
الهدف الحقيقي لهذه التقنية هو قطع الألعاب (chunks)، وكل قطعة فريدة، مما يجعل استخدام النسخ مستحيلاً. لذا، فقد أخذت هذه التقنية وطبقتها على كيفية عرض القطع. المؤشرات الأولية واعدة بالفعل.
Speaker A
لقد وصلنا إلى 50 إطاراً في الثانية. هذا أعلى من خط الأساس البالغ حوالي 30. ومع ذلك، نحن نواجه بعض نوبات البطء الشديدة.
Speaker A
لكن لا بأس بذلك. هذا تطبيق أولي، ولم يتم تحسين أي شيء بعد، ولا حتى تقليم المشاهد.
Speaker A
يتم حالياً عرض القطع التي تقع خلف الكاميرا أيضاً. ما نحتاجه هو إضافة تقليم للمنظور (Frustum culling)، بحيث يتم عرض القطع الموجودة داخل رؤية الكاميرا فقط. إحدى طرق القيام بذلك هي المرور عبر كل شبكة في المخزن المؤقت، والتحقق من حدودها
Speaker A
مقابل الكاميرا، وتحديث وسائطها وفقاً لذلك. لكن هذا سيكون بطيئاً، خاصة وأننا نحاول بالفعل عرض حوالي 20,000 قطعة. لذا، بدلاً من ذلك، دعنا نقوم بهذا العمل على بطاقة الرسوميات أيضاً، باستخدام "compute shader". يمكنه معالجة مئات الآلاف من الحدود بالتوازي وتحديث
Speaker A
الوسائط مباشرة قبل العرض. حسناً، الخبر السار هو أنه نجح. ومع ذلك، لم يتحسن الأداء حقاً. لا نزال عند حوالي 50 إطاراً في الثانية. ولكن على الأقل، انخفضت نوبات البطء. يبدو أن العمل الإضافي الذي يتطلبه التقليم يلغي أي مكاسب
Speaker A
نحصل عليها من تقليل العرض. هذا يعطيني فكرة. قطعنا ليست في مواقع عشوائية. بل في مواقع محددة جيداً.
Speaker A
ماذا لو قمنا بتجميعها في هيكل "شجرة ثمانية" (octree) بدلاً من فحص حدود كل قطعة على حدة؟ يعمل هيكل الشجرة الثمانية هكذا. نأخذ حداً واحداً كبيراً. هنا اخترت 32 في 32 في 32 قطعة.
Speaker A
ونختبر ما إذا كانت تظهر على الشاشة. إذا لم تكن كذلك، نتجاهل كل تلك القطع دفعة واحدة، أي جميع القطع البالغ عددها 32,768. إذا كانت تظهر على الشاشة، نقسم ذلك الحد إلى ثمانية حدود أصغر، يحتوي كل منها على 16 في
Speaker A
16 في 16 قطعة. ونعيد اختبار كل من الثمانية. أي منها يفشل يتم تجاهله مع فروعها التابعة. نستمر في التقسيم إلى مجموعات أصغر فأصغر من ثمانية حتى يتم اختبار كل قطعة أو تجاهلها.
Speaker A
تحسين آخر يمكننا القيام به هو أنه إذا كانت طبقة الشجرة الثمانية بالكامل داخل منظور الرؤية، فيمكننا ضمان أن جميع فروعها التابعة داخل المنظور أيضاً. لذا، يمكننا إضافتها جميعاً مباشرة إلى قائمة العرض دون اختبار كل واحدة على حدة. هذه التقنية أسرع
Speaker A
بكثير، حيث يمكننا تجميع اختبارات القطع معاً لتقليم أسرع، ولا نحتاج أبداً إلا لإعادة اختبار الفروع التي تتداخل مع مستوى المنظور. لنطبق هذا ونختبر مرة أخرى.
Speaker A
حسناً، هذا أفضل بكثير. أنا أحصل على أكثر من 170 إطاراً في الثانية. هذا أفضل بست مرات من خط الأساس لدينا.
Speaker A
لكننا لا نزال نواجه بعض نوبات البطء، حيث تنخفض أحياناً إلى 10 إطارات في الثانية.
Speaker A
ومع ذلك، يبدو الأمر أفضل بكثير. لذا، دعونا الآن نرى ما إذا كان بإمكاننا التخلص من نوبات البطء المتبقية تلك. أعتقد الآن أن تلك الارتفاعات المتبقية ناتجة عن كون الشبكة الضخمة لدينا كبيرة للغاية. نعم، الحجم الأكبر أفضل لطلبات الرسم. لكن، هذا يجعل
Speaker A
مهمة إضافة وإزالة الشبكات أبطأ. على الرغم من أننا لا نحتاج إلى إعادة بناء الشبكة، إلا أننا ما زلنا بحاجة للعثور على مساحات فارغة. ومع وجود أكثر من 20,000 قطعة تملأ شبكة واحدة، فهذه مساحة ضخمة للبحث فيها، مما يفسر سبب رؤيتنا
Speaker A
لارتفاعات عشوائية. ما نحتاج إلى القيام به هو إضافة خاصية الترحيل (Paging). تقسيم شبكتنا الضخمة إلى بضع شبكات أصغر بمجرد الوصول للسعة المحددة، وهذا يعطينا ميزة إضافية وهي الحصول على حد لا نهائي من الرؤوس.
Speaker A
سابقاً كنا مقيدين بسعة الشبكة الضخمة، التي كانت كبيرة لكنها محدودة، وكنا نفقد القطع بصمت إذا نفدت المساحة. الآن، عندما تنفد المؤشرات، يمكننا الانتقال بسلاسة إلى شبكة ضخمة أخرى. هذا يزيد قليلاً من طلبات الرسم لدينا.
Speaker A
الآن، أصبح هناك طلب واحد لكل مجموعة، لكني آمل أن تعمل الشبكات الأصغر بشكل أسرع وتعوض عن الطلبات الإضافية. لقد نجح هذا.
Speaker A
ما زلنا نحصل على حوالي 170 إطاراً في الثانية. لتجاوز حاجز الـ 200 إطار في الثانية، سنحتاج إلى اتخاذ إجراءات أكثر صرامة.
Speaker A
لزيادة السرعة، أعتقد أنه يجب علينا تقليل حجم كل شبكة على حدة. ولكن للقيام بذلك، يجب علينا تبسيط شبكاتنا.
Speaker A
إحدى طرق القيام بذلك تسمى الشبكة الجشعة (Greedy Meshing). ومع ذلك، واجهنا مشكلة فورية.
Speaker A
سطح "بلانيت سميث" منحني ومصنوع من أشكال سداسية. لذا، للأسف، لا يمك
Speaker A
من المعلومات. عادة ما يكون موقعها مكتوباً بصيغة "فلوت 3"، وهو ما يعادل 12 بايت من البيانات. كما تحتوي أيضاً على متجه عمودي، 12 بايت أخرى، وفي حالتنا، إحداثيات UVW، وهي 12 بايت إضافية.
Speaker A
يحتوي "بلانيت سميث" أيضاً على بعض بيانات الرؤوس الإضافية. 4 بايت للون الرأس، وبايت إضافي للانسداد المحيطي، وبايتان لبيانات الإضاءة، وبايت أخير لبعض إعدادات الإضاءة.
Speaker A
وأخيراً، أربعة بايت لمؤشر النسخة الخاص بنا. هذا ليس طبيعياً، ولكنه مطلوب لعملية العرض غير المباشر لدينا. يصل مجموع ذلك إلى 48 بايت ضخمة من البيانات لكل رأس.
Speaker A
لنحاول ضغط ذلك ونرى ما يمكننا فعله. فكرتي الأولى هي حزم البيانات الإضافية معاً باستخدام إزاحة البت. يمكننا حزم بعض تلك البيانات بشكل أكثر تلاصقاً، لكنها لن توفر سوى بضعة بايتات. نحن بحاجة إلى شيء أكثر جذرية بكثير.
Speaker A
فكرتي التالية هي التخلص من النواظم تماماً. نحن في الواقع لا نحتاج إليها. النواظم في Planet Smith مسطحة دائماً، لذا يمكننا إعادة بنائها عند العرض. هذا يقلص الحجم فوراً إلى 36 بايت. التالي في قائمة الحذف هو 12 بايت الخاصة بإحداثيات UV،
Speaker A
والتي تبدو مبالغاً فيها أيضاً. لدينا إحداثيات UVW حيث W هو فهرس النسيج. دعنا نتجاهل W الآن ونركز على تلك الثمانية بايت الخاصة بجزء UV.
Speaker A
إحداثيات UV يمكن التنبؤ بها لأنها تعتمد على الفوكسل. ماذا لو قمنا ببناء جدول بحث بجميع المواقع المستخدمة وقمنا بالفهرسة فيه بدلاً من تسجيل مواقع UV الفعلية؟ اخترت جدولاً بـ 256 مدخلاً، مما يقلل الثمانية بايت الخاصة بـ UV إلى
Speaker A
بايت واحد. هذا يوصلنا إلى 29 بايت. الآن، قيمة W تمثل 4 مليارات نسيج مختلف. سيكون لدى Planet Math المزيد من الأنسجة مستقبلاً، لكن لنكتفِ بـ 11 بت حالياً، مما يمنحنا 2048 نسيجاً. وهو الحد الأقصى للأنسجة التي يمكننا امتلاكها
Speaker A
في مادة واحدة على أي حال. لذا، إذا أردنا المزيد من الأنسجة لاحقاً، سنحتاج لتقسيم المواد بغض النظر. هذا يوفر بايتين إضافيين ليصل المجموع إلى 27. يمكننا إجراء نفس معاملة جدول البحث للألوان. لنخصص بايتين للألوان بدلاً من أربعة، مما يمنحنا
Speaker A
32 ألف لون مختلف للتلوين، وهو كافٍ جداً. هذا يخفض المجموع إلى 25 بايت. أخيراً، لنجمع كل تلك البيانات المتبقية الصغيرة معاً. فهرس النسيج، والانسداد المحيطي، وإضاءة الكتلة، وإعدادات الإضاءة في كتلة واحدة مشتركة باستخدام إزاحة البت. هذا يضغطها لتصبح 3 بايت
Speaker A
مجتمعة، مما يجعل مجموعنا 22 بايت. بالفعل أقل من نصف ما بدأنا به. يتبقى لدينا 12 بايت للموقع، وبايت واحد لفهرس UV، وبايتان للألوان، و 3 بايت للبيانات المتنوعة، و 4 بايت لمعرف النسخة.
Speaker A
هذا يساوي 22 بايت. لكن أعتقد أنه يمكننا تحقيق ما هو أفضل. دعونا ننظر إلى الموقع الذي يستخدم 12 بايت. هل نحتاج فعلاً إلى كل ذلك؟ 12 بايت تعني 4 بايت لكل محور، مما يسمح لنا بوصف 4 مليارات موقع لكل محور
Speaker A
. لكن لدينا بيانات فوكسل، لذا يمكننا وضع بعض الافتراضات. إذا قسمنا كل محور إلى 4 مليارات، فسنحصل على دقة 4 نانومتر. هذا صغير بشكل سخيف. لن تلاحظ ذلك أبداً. إذا قمت بتخزين المواقع بنصف الحجم، 6 بايت، فهذا يعني 2 بايت لكل
Speaker A
محور ودقة 0.5 ملم. مجدداً، هي صغيرة جداً وأعتقد أنها تسوية مقبولة. صغيرة بما يكفي بحيث لن يتمكن الناس من ملاحظة الفرق . وهذا يخفض إجمالي حجم بياناتنا إلى 16 بايت.
Speaker A
أي ثلث ما بدأنا به دون المساس بأي ميزة. هذا التحسين منحنا دفعة كبيرة، وأصبحت اللعبة الآن تعمل بأكثر من 200 إطار في الثانية دون أي تقطيع ملحوظ. أعتقد أنه يمكنني القول بأمان أن هذا كافٍ في الوقت الحالي. والأمر
Speaker A
يزداد تحسناً. كانت لعبة "بلانيت سميث" تنهار إذا قمت بزيادة مسافة الرؤية لأكثر من 40 جزءاً. ماذا لو رفعتها الآن إلى 120 جزءاً؟ هذا ليس أصعب بثلاث مرات فحسب.
Speaker A
تتضاعف المساحة أربع مرات في كل مرة تتضاعف فيها مسافة الرؤية. لذا، فهذا أصعب بتسع مرات. لن أكذب عليكم وأقول أنها سلسة تماماً، لكنها ليست سيئة. بالنسبة لأجزاء بدقة كاملة، هذا أداء جنوني. لدينا حوالي مليار نقطة رأسية يتم عرضها الآن مع تحميل 1.8
Speaker A
مليون جزء و 8 مليارات كتلة. تخيل ما قد يكون ممكناً بمجرد إضافة مستوى التفاصيل للأجزاء البعيدة. إذا أردت معرفة ما سيحدث عند إضافة مستوى التفاصيل وكيفية صنع الميزات الأخرى التي ربما لاحظتها في هذا الفيديو، تأكد من الاشتراك في القناة.
Speaker A
ولا تنسَ إضافة " بلانيت سميث" إلى قائمة أمنياتك على " ستيم". إنها واحدة من أفضل الطرق التي يمكنك بها مساعدتنا. وإذا كنت ترغب في مساعدة " بلانيت سميث" بشكل مباشر أكثر، فلا يزال بإمكانك ذلك. لديّ مساهمات "كيك ستارتر"
Speaker A
متأخرة على موقعي حيث يمكنك شراء اللعبة مسبقاً والحصول على مكافآت حصرية مثل أن تصبح مختبراً للنسخة الأولية. شكراً لجميع أعضاء قناتنا الرائعين الذين ساعدوا في جعل مقاطع فيديو كهذه ممكنة.
Speaker A
شكراً للمشاهدة وأراكم في سجل التطوير القادم.
Topics:عرض الرسومياتمحرك الألعاببيانات الرؤوسالشبكة الضخمةتقنية العرض غير المباشرتقليم المنظورشجرة ثمانيةترحيل الشبكاتتبسيط الشبكاتPlanet Smith











