تجربة الهوبيت

إضفاء الحيوية على منتصف الكرة الأرضية باستخدام تقنية WebGL للأجهزة الجوّالة

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

في وقت سابق من هذا العام، بدأنا مشروعًا مع أصدقاء من Google ووارنر براذرز. لتقديم تجربة ويب على الأجهزة الجوّالة في المقام الأول لفيلم الهوبيت الجديد، The Hobbit: The Desolation of Smaug. لقد كان إنشاء تجربة Chrome للأجهزة الجوّالة مليئة بالوسائط المتعددة مهمة ملهمة وصعبة حقًا.

تم تحسين التجربة لمتصفح Chrome لنظام التشغيل Android على أجهزة Nexus الجديدة، حيث يمكننا الآن الوصول إلى WebGL وWeb Audio. ومع ذلك، يمكن الوصول إلى جزء كبير من التجربة من خلال الأجهزة والمتصفحات التي لا تستخدم WebGL أيضًا بفضل التركيب السريع للأجهزة والرسوم المتحركة في CSS.

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

تحديات WebGL على الأجهزة الجوّالة

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

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

  • استخدام نماذج منخفضة الأشكال المضلعة
  • استخدام زخارف منخفضة الدقة
  • تقليل عدد الرسومات المرسومة قدر الإمكان من خلال دمج الأشكال الهندسية
  • تبسيط المواد والإضاءة
  • إزالة تأثيرات المشاركة وإيقاف التنقيح
  • تحسين أداء JavaScript
  • عرض لوحة WebGL بنصف الحجم وتوسيعه باستخدام CSS

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

استخدام نماذج منخفضة الأشكال المضلعة

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

أحد ترولات غابة "ترولشو"
أحد ترولات غابة "ترول شو"

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

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

استخدام زخارف منخفضة الدقة

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

زخرفة لأحد ترولات غابة "ترول شو"
زخرفة لأحد ترولات غابة "ترول شو"
(الحجم الأصلي 512×512 بكسل)

تبسيط المواد والإضاءة

ويمكن أن يؤثر اختيار المواد بشكل كبير في الأداء ويجب إدارتها بحكمة على الأجهزة الجوّالة. إن استخدام MeshLambertMaterial (لكل حساب ضوء رأسي) في three.js بدلاً من MeshPhongMaterial (لكل حساب ضوء texel) هو أحد الإجراءات التي استخدمناها لتحسين الأداء. حاولنا في الأساس استخدام أدوات تظليل بسيطة من خلال أقل عمليات حسابية للإضاءة قدر الإمكان.

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

scene.overrideMaterial = new THREE.MeshBasicMaterial({color:0x333333, wireframe:true});

تحسين أداء JavaScript

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

إنّ تعديل العناصر المخصّصة مسبقًا في حلقات بدلاً من إنشاء عناصر جديدة يُعدّ خطوة مهمة لتجنُّب "العوائق" في جمع البيانات أثناء اللعب.

على سبيل المثال، ضع في اعتبارك تعليمة برمجية مثل هذه:

var currentPos = new THREE.Vector3();

function gameLoop() {
  currentPos = new THREE.Vector3(0+offsetX,100,0);
}

يتجنّب الإصدار المحسَّن من هذه الحلقة إنشاء كائنات جديدة يجب أن تكون مجمّعة غير كافية:

var originPos = new THREE.Vector3(0,100,0);
var currentPos = new THREE.Vector3();
function gameLoop() {
  currentPos.copy(originPos).x += offsetX;
  //or
  currentPos.set(originPos.x+offsetX,originPos.y,originPos.z);
}

على قدر الإمكان، يجب على معالِجات الأحداث تعديل الخصائص فقط والسماح لمقبض حلقة العرض requestAnimationFrame بتعديل الجزء.

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

عرض لوحة WebGL بنصف الحجم وتوسيعه باستخدام CSS

وربما يكون حجم لوحة WebGL هو المعلمة الأكثر فعالية التي يمكنك تعديلها لتحسين الأداء. كلما كانت اللوحة التي تستخدمها أكبر لرسم المشهد الثلاثي الأبعاد، يلزم رسم عدد أكبر من وحدات البكسل على كل إطار. يؤثر ذلك بالطبع في الأداء.لذا، يجب على جهاز Nexus 10 - الذي يتميز بشاشته العالية الكثافة 2560x1600 بكسل - أن يدفع 4 أضعاف عدد البكسل كجهاز لوحي منخفض الكثافة. ولتحسين ذلك على الأجهزة الجوّالة، نستخدم خدعة حيث يتم ضبط اللوحة على نصف حجمها (50%) ثم زيادتها إلى الحجم المطلوب (100%) باستخدام عمليات تحويل CSS ثلاثية الأبعاد مع تسريع الأجهزة. الجانب السلبي لهذه الصورة هو صورة متقطّعة حيث يمكن أن تشكل الخطوط الرقيقة مشكلة، ولكن على الشاشة عالية الدقة، يكون التأثير ليس بهذا السوء. الأمر يستحق المحاولة الإضافية بالتأكيد.

المشهد نفسه بدون تحجيم لوحة الرسم على جهاز Nexus 10 (16 لقطة في الثانية) وتغيير حجمه إلى 50% (33 لقطة في الثانية)
سيكون المشهد نفسه بدون تكبير اللوحة على جهاز Nexus 10 (16 لقطة في الثانية) وبنسبة 50% (33 لقطة في الثانية).

العناصر كوحدات أساسية

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

أشكال ثلاثية الأبعاد من الكتل البرمجية الإنشائية المستخدمة في متاهة "دول غولدور"
وحدات بناء ثلاثية الأبعاد لأجزاء مُستخدَمة في متاهة "دول غولدور"

لدينا في Rivendell عدد من الأقسام الأساسية التي نغير موضعها باستمرار بعمق Z مع تقدّم المستخدم في رحلته. وعندما يتجاوز المستخدم أقسامًا، يتم تغيير موضعها في المسافة البعيدة.

وفي قلعة Dol Guldur، أردنا إعادة إنشاء المتاهة لكل لعبة. وللقيام بذلك، ابتكرنا نصًا يعيد إنشاء المتاهة.

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

الشيء الكبير التالي الذي يجب التعامل معه هو تفاعل المستخدم. على سطح المكتب لديك إدخالات الماوس ولوحة المفاتيح؛ وعلى الأجهزة المحمولة يتفاعل المستخدمون مع اللمس والتمرير والتصغير والتصغير واتجاه الجهاز وما إلى ذلك.

استخدام التفاعل باللمس في تجارب الويب على الأجهزة الجوّالة

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

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

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

يُرجى العِلم أنّها تتيح اللمس المتعدّد: event.touches هو مصفوفة من كل اللمسات. وفي بعض الحالات، يكون من المفيد أكثر النظر إلى event.targetTouches أو event.changedTouches بدلاً من ذلك والتفاعُل مع اللمسات التي تهتم بها. للفصل بين النقرات والتمريرات السريعة، نستخدم مهلة قبل أن نتحقق مما إذا كانت اللمسة قد تحركت (التمرير السريع) أو لا تزال لا تزال (النقر). للتصغير، نقيس المسافة بين اللمستين الأوليتين وكيف يتغير ذلك بمرور الوقت.

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

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

ملخّص

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

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

تم إطلاق التجربة وكانت رحلة رائعة. نأمل أن يعجبك ذلك.

هل تريد تجربتها؟ خذ رحلتك إلى ميدل إيرث.