في ما يلي بعض الأساسيات التي تساعدك في الاستعداد لمجموعة من التجارب الغامرة، مثل الواقع الافتراضي والواقع المعزّز وكل ما بينهما.
أصبح بإمكانك الاستفادة من التجارب الغامرة على الويب في الإصدار 79 من Chrome. تتيح واجهة برمجة التطبيقات WebXR Device API تجربة الواقع الافتراضي، بينما تتوفّر إمكانية استخدام الواقع المعزّز في الإصدار 81 من Chrome. في المقابل، يتيح تحديث GamePad API استخدام عناصر التحكّم المتقدّمة في الواقع الافتراضي. ستتوافق المتصفّحات الأخرى مع هذه المواصفات قريبًا، بما في ذلك Firefox Reality وOculus Browser وEdge ومتصفّح Helio من Magic Leap، وغيرها.
هذه المقالة هي الأولى في سلسلة مقالات حول الويب التفاعلي. يتناول هذا الجزء كيفية إعداد تطبيق WebXR أساسي، بالإضافة إلى بدء جلسة XR وإنهائها. ستتناول المقالات اللاحقة حلقة الإطارات (التي تشكّل أساس تجربة WebXR)، وتفاصيل الواقع المعزّز، وWebXR Hit Test API، وهي وسيلة لرصد الأسطح في جلسة واقع معزّز. ما لم يُذكر خلاف ذلك، ينطبق كل ما أتناوله في هذه المقالة والمقالات اللاحقة بالتساوي على كل من الواقع المعزّز والواقع الافتراضي.
ما هو الويب التفاعلي؟
على الرغم من أنّنا نستخدم مصطلحَين لوصف التجارب الغامرة، وهما الواقع المعزّز والواقع الافتراضي، يرى الكثيرون أنّهما يقعان على طيف يبدأ من الواقع الكامل وينتهي بالواقع الافتراضي الكامل، مع درجات من الانغماس بينهما. يهدف الحرف X في XR إلى التعبير عن هذا المفهوم من خلال كونه نوعًا من المتغيرات الجبرية التي تشير إلى أي شيء في نطاق التجارب الغامرة.
تشمل أمثلة التجارب الغامرة ما يلي:
- الألعاب
- الفيديوهات بنطاق 360 درجة
- فيديوهات تقليدية ثنائية الأبعاد (أو ثلاثية الأبعاد) معروضة في محيط غامر
- شراء منزل
- معاينة المنتجات في منزلك قبل شرائها
- الفن الغامر
- فكرة رائعة لم يفكّر فيها أحد بعد
المفاهيم والاستخدام
سأشرح بعض الأساسيات حول استخدام WebXR Device API. إذا كنت بحاجة إلى معلومات أكثر تفصيلاً مما قدّمته، يمكنك الاطّلاع على عينات WebXR الخاصة بفريق عمل Immersive Web Working Group أو المواد المرجعية المتزايدة في شبكة مطوّري Mozilla. إذا كنت على دراية بالإصدارات المبكرة من WebXR Device API، عليك إلقاء نظرة سريعة على كل هذه المواد. حدثت تغييرات.
يستند الرمز البرمجي الوارد في هذه المقالة إلى نموذج بسيط جدًا من مجموعة عمل Immersive Web (العرض التوضيحي، المصدر)، ولكن تم تعديله لتوضيحه وتبسيطه.
وقد تطلّب إنشاء مواصفات WebXR وضع تدابير أمان وخصوصية لحماية المستخدمين. وبالتالي، يجب أن تلتزم عمليات التنفيذ بمتطلبات معيّنة. يجب أن تكون صفحة الويب أو التطبيق نشطَين ومحدَّدَين قبل أن يتمكّنا من طلب أي معلومات حساسة من المشاهد. يجب عرض صفحات الويب أو التطبيقات عبر بروتوكول HTTPS. تم تصميم واجهة برمجة التطبيقات نفسها لحماية المعلومات التي يتم الحصول عليها من أجهزة الاستشعار والكاميرات، وهي المعلومات التي تحتاج إليها لتعمل.
طلب جلسة
يتطلّب بدء جلسة XR إيماءة من المستخدم. للحصول على ذلك، استخدِم ميزة
التعرّف على الميزات لاختبار XRSystem (عبر navigator.xr) وإجراء مكالمة إلى
XRSystem.isSessionSupported(). يُرجى العِلم أنّه في الإصدارَين 79 و80 من Chrome، كان اسم العنصر
XRSystem هو XR.
في المثال أدناه، أشرتُ إلى أنّني أريد جلسة واقع افتراضي من النوع 'immersive-vr'. أنواع الجلسات الأخرى هي 'immersive-ar' و'inline'. تُستخدَم الجلسة المضمّنة لعرض المحتوى ضمن HTML، وهي مخصّصة بشكل أساسي لعرض المحتوى الترويجي. يوضّح نموذج جلسة الواقع المعزّز الغامر ذلك. سأشرح ذلك في مقالة لاحقة.
بعد التأكّد من توفّر جلسات الواقع الافتراضي، أفعّل زرًا يتيح لي الحصول على إيماءة من المستخدم.
if (navigator.xr) {
const supported = await navigator.xr.isSessionSupported('immersive-vr');
if (supported) {
xrButton.addEventListener('click', onButtonClicked);
xrButton.textContent = 'Enter VR';
xrButton.enabled = supported; // supported is Boolean
}
}
بعد تفعيل الزر، أنتظر حدث ناتج عن النقر ثم أطلب جلسة.
let xrSession = null;
function onButtonClicked() {
if (!xrSession) {
navigator.xr.requestSession('immersive-vr')
.then((session) => {
xrSession = session;
xrButton.textContent = 'Exit XR';
onSessionStarted(xrSession);
});
} else {
xrSession.end();
}
}
لاحظ المخطط الهرمي للعناصر في هذا الرمز. يتم نقلها من navigator إلى xr إلى مثيل XRSession. في الإصدارات الأولى من واجهة برمجة التطبيقات، كان على النص البرمجي طلب جهاز قبل طلب جلسة. الآن، يتم الحصول على الجهاز بشكل ضِمني.
إدخال جلسة
بعد الحصول على جلسة، يجب أن أبدأها وأدخلها. لكن أولاً، يجب إعداد بعض التفاصيل. تحتاج الجلسة إلى معالج أحداث onend حتى يمكن إعادة ضبط التطبيق أو صفحة الويب عند خروج المستخدم.
سأحتاج أيضًا إلى عنصر <canvas> لرسم المشهد عليه. يجب أن يكون
WebGLRenderingContext
أو
WebGL2RenderingContext
متوافقًا مع XR.
يتم تنفيذ كل الرسومات باستخدامها أو باستخدام إطار عمل مستند إلى WebGL، مثل
Three.js.
بعد أن أصبح لديّ مكان للرسم، أحتاج إلى مصدر للمحتوى الذي سأستند إليه في الرسم. لذلك، أنشئ مثيلاً من XRWebGLLayer. أربطها بلوحة العرض عن طريق استدعاء XRSession.updateRenderState().
بعد الدخول إلى جلسة، أحتاج إلى طريقة لتحديد أماكن العناصر في الواقع الافتراضي. أحتاج إلى مساحة مرجعية. مساحة مرجعية 'local-floor' هي مساحة يكون فيها المرجع بالقرب من المشاهد ويكون المحور y عند 0 على مستوى الأرضية، ومن غير المتوقّع أن يتحرّك. هناك أنواع أخرى من مساحات
المراجع،
ولكن هذا موضوع أكثر تعقيدًا من أن أتطرّق إليه هنا. أحفظ مساحة المرجع في متغيّر لأنّني سأحتاج إليها عند الرسم على الشاشة.
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
let canvas = document.createElement('canvas');
webGLRenContext = canvas.getContext('webgl', { xrCompatible: true });
xrSession.updateRenderState({
baseLayer: new XRWebGLLayer(xrSession, webGLRenContext)
});
xrSession.requestReferenceSpace('local-floor')
.then((refSpace) => {
xrRefSpace = refSpace;
xrSession.requestAnimationFrame(onXRFrame);
});
}
بعد الحصول على مساحة مرجعية، أكتب XRSession.requestAnimationFrame().
هذه هي بداية عرض المحتوى الافتراضي، ويتم ذلك في حلقة
الإطارات.
تشغيل حلقة إطارات
حلقة الإطارات هي حلقة لا نهائية يتحكّم فيها وكيل المستخدم، ويتم فيها رسم المحتوى بشكل متكرّر على الشاشة. يتم عرض المحتوى في مربّعات منفصلة تُعرف باسم إطارات. يؤدي تسلسل اللقطات إلى إنشاء وهم الحركة. بالنسبة إلى تطبيقات الواقع الافتراضي، يمكن أن يتراوح عدد اللقطات في الثانية بين 60 و144. تعمل ميزة الواقع المعزّز على Android بمعدّل 30 لقطة في الثانية. يجب ألا يفترض الرمز أي عدد لقطات في الثانية معيّن.
تتمثل العملية الأساسية لحلقة الإطارات في ما يلي:
- تواصل هاتفيًا مع "
XRSession.requestAnimationFrame()". استجابةً لذلك، يستدعي وكيل المستخدمXRFrameRequestCallbackالذي تحدّده أنت. - داخل دالّة رد الاتصال، اتّبِع الخطوات التالية:
- الاتصال بـ "
XRSession.requestAnimationFrame()" مرة أخرى - الحصول على وضعية المشاهد
- مرِّر (اربط)
WebGLFramebufferمنXRWebGLLayerإلىWebGLRenderingContext. - كرِّر كل عنصر من عناصر
XRView، واستردِXRViewportمنXRWebGLLayer، ثم مرِّره إلىWebGLRenderingContext. - ارسم شيئًا في إطار التخزين المؤقت.
- الاتصال بـ "
يشرح الجزء المتبقي من هذه المقالة الخطوة 1 وجزءًا من الخطوة 2، أي إعداد XRFrameRequestCallback واستدعاؤه. سيتم تناول العناصر المتبقية من الخطوة 2 في الجزء الثاني.
XRFrameRequestCallback
يتم تحديد XRFrameRequestCallback من قِبل المستخدم. تتلقّى هذه الدالة مَعلمتَين: DOMHighResTimeStamp وXRFrame. يوفّر العنصر XRFrame المعلومات اللازمة لعرض إطار واحد على الشاشة. يُستخدَم الوسيط
DOMHighResTimeStamp في المستقبل.
قبل فعل أي شيء آخر، سأطلب إطار الصورة المتحركة التالي. كما ذكرنا سابقًا، يحدّد وكيل المستخدم توقيت الإطارات استنادًا إلى الأجهزة الأساسية. يضمن طلب الإطار التالي أولاً استمرار حلقة الإطارات في حال حدوث خطأ أثناء عملية معاودة الاتصال.
function onXRFrame(hrTime, xrFrame) {
let xrSession = xrFrame.session;
xrSession.requestAnimationFrame(onXRFrame);
// Render a frame.
}
في هذه المرحلة، حان الوقت لرسم شيء للمشاهد. سنتناول هذا الموضوع في الجزء الثاني. قبل الانتقال إلى هناك، سأوضّح لك كيفية إنهاء جلسة.
إنهاء الجلسة
قد تنتهي الجلسة الغامرة لعدة أسباب، بما في ذلك إنهاؤها من خلال الرمز الخاص بك عن طريق استدعاء XRSession.end(). وتشمل الأسباب الأخرى فصل سماعة الرأس أو تحكّم تطبيق آخر بها. لهذا السبب، يجب أن يراقب التطبيق الذي يعمل بشكل سليم الحدث end. وعند حدوث ذلك، تجاهِل الجلسة وعناصر العرض ذات الصلة. لا يمكن استئناف جلسة غامرة منتهية. لإعادة الدخول إلى التجربة الغامرة، يجب أن يبدأ تطبيقي جلسة جديدة.
تذكَّر من بدء جلسة أنّني أضفت أثناء عملية الإعداد معالج أحداث onend.
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
// More setup…
}
داخل معالج الأحداث، استعِد حالة التطبيق قبل أن يبدأ المستخدم جلسة.
function onSessionEnded(event) {
xrSession = null;
xrButton.textContent = 'Enter VR';
}
الخاتمة
لم أشرح كل ما تحتاج إليه لكتابة تطبيق Web XR أو تطبيق واقع معزّز. نأمل أن تكون المعلومات التي قدّمناها كافية لتتمكّن من فهم الرمز بنفسك والبدء بتجربته. في المقالة التالية، سأشرح حلقة الإطار، وهي العملية التي يتم من خلالها رسم المحتوى على الشاشة.