مرحبًا بك في شبكة الويب المجسَّمة

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

Joe Medley
Joe Medley

الويب الغامر هو تجارب العالم الافتراضي التي يتم استضافتها من خلال المتصفّح. ويشمل ذلك تجارب الواقع الافتراضي بالكامل التي تظهر في المتصفّح أو في سماعات الرأس المزوّدة بتقنية الواقع الافتراضي، مثل Daydream من Google وOculus Rift وSamsung Gear VR وHTC Vive وسماعات الرأس Windows Mixed Reality، بالإضافة إلى تجارب الواقع المعزّز المطوّرة للأجهزة الجوّالة المزوّدة بتقنية الواقع المعزّز.

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

تشمل أمثلة التجارب الشاملة ما يلي:

  • فيديوهات شاملة بزاوية 360 درجة
  • فيديوهات تقليدية ثنائية الأبعاد (أو ثلاثية الأبعاد) يتم عرضها في محيط مجسم
  • الرسومات البيانية
  • التسوّق من المنزل
  • فنون
  • أفكار رائعة لم يسبق لأحد التفكير بها

كيف أصِل إلى هناك؟

لقد أصبح الويب الشامل متاحًا منذ عام تقريبًا في شكله الأولي. تم إجراء ذلك من خلال واجهة برمجة التطبيقات WebVR 1.1 ، والتي كانت متوفرة في مرحلة التجربة والتقييم منذ إصدار Chrome 62. تتوفّر واجهة برمجة التطبيقات هذه أيضًا في Firefox وEdge، بالإضافة إلى مكتبة polyfill لمتصفّح Safari.

ولكن حان الوقت للانتقال إلى الخطوة التالية.

انتهت مرحلة التجربة والتقييم في 24 تموز (يوليو) 2018، وتم استبدال المواصفات بـ WebXR Device API ومرحلة تجربة وتقييم جديدة.

ماذا حدث للإصدار 1.1 من WebVR؟

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

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

تم تصميم واجهة برمجة التطبيقات WebXR Device API وتسميتها مع وضع حالات الاستخدام الموسّعة هذه في البال، كما أنّها توفّر مسارًا أفضل للمضي قدمًا. تعهد مستخدمو WebVR بالانتقال إلى WebXR Device API.

ما هي WebXR Device API؟

وكما هي الحال في مواصفات WebVR قبلها، فإنّ واجهة برمجة التطبيقات WebXR Device API هي منتج تابع لمجموعة Immersive Web Community Group التي تضمّ مساهمين من Google وMicrosoft وMozilla وشركات أخرى. إنّ الحرف "X" في الواقع المعزّز هو متغيّر حسابي يشير إلى أيّ شيء في مجموعة التجارب الغامرة. وهو متاح في مرحلة التجربة والتقييم السابقة المذكورة سابقًا وكذلك من خلال استخدام polyfill.

عند نشر هذه المقالة في الأصل خلال فترة الإصدار التجريبي من Chrome 67، تم تفعيل إمكانات الواقع الافتراضي فقط. تم توفير تقنية الواقع المعزّز في الإصدار 69 من Chrome. يمكنك الاطّلاع على المزيد من المعلومات عن ذلك في مقالة الواقع المعزّز على الويب.

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

في هذه المقالة، سأتناول بدء جلسة الواقع المعزّز وإيقافها وتشغيلها، بالإضافة إلى بعض الأساسيات حول معالجة الإدخال.

لن أتطرق إلى كيفية رسم محتوى الواقع المعزّز/VR على الشاشة. لا توفّر واجهة برمجة التطبيقات WebXR Device API ميزات عرض الصور. فالقرار يعود لك. يتم الرسم باستخدام واجهات برمجة تطبيقات WebGL. يمكنك إجراء ذلك إذا كنت طموحًا حقًا. ومع ذلك، ننصحك باستخدام إطار عمل. تستخدم نماذج الويب الشاملة أحد نماذج الويب التي تم إنشاؤها خصيصًا للعروض التوضيحية والتي تُسمى Cottontail. يتيح Three.js استخدام WebXR منذ شهر أيار (مايو). لم أسمع أي شيء عن A-Frame.

بدء تطبيق وتشغيله

في ما يلي العملية الأساسية:

  1. اطلب جهاز XR.
  2. اطلب جلسة واقع ممحوّر إذا كانت متاحة. إذا كنت تريد أن يضع المستخدم هاتفه في سماعة الرأس، فإن ذلك يسمى جلسة غامرة وتتطلب إيماءة من المستخدم للدخول.
  3. استخدِم الجلسة لتشغيل حلقة عرض توفّر 60 إطارًا للصورة في الثانية. ارسم المحتوى المناسب على الشاشة في كل إطار.
  4. يمكنك تشغيل حلقة التقديم إلى أن يقرر المستخدم الخروج.
  5. إنهاء جلسة الواقع المعزّز

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

طلب جهاز الواقع المعزّز

حيث تتعرف على الرمز القياسي لاكتشاف الميزات. يمكنك تضمين هذا الرمز في دالة باسم checkForXR() مثلاً.

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

if (navigator.xr) {
    navigator.xr.requestDevice()
    .then(xrDevice => {
    // Advertise the AR/VR functionality to get a user gesture.
    })
    .catch(err => {
    if (err.name === 'NotFoundError') {
        // No XRDevices available.
        console.error('No XR devices available:', err);
    } else {
        // An error occurred while requesting an XRDevice.
        console.error('Requesting XR device failed:', err);
    }
    })
} else{
    console.log("This browser does not support the WebXR API.");
}

طلب جلسة واقع ممحوّر

الآن بعد أن أصبح لدينا الجهاز وإيماءة المستخدم، حان وقت تسجيل جلسة. لإنشاء جلسة، يحتاج المتصفّح إلى لوحة للرسم عليها.

xrPresentationContext = htmlCanvasElement.getContext('xrpresent');
let sessionOptions = {
    // The immersive option is optional for non-immersive sessions; the value
    //   defaults to false.
    immersive: false,
    outputContext: xrPresentationContext
}
xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Use a WebGL context as a base layer.
    xrSession.baseLayer = new XRWebGLLayer(session, gl);
    // Start the render loop
})

تشغيل حلقة التقديم

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

في ما يلي العملية الأساسية لحلقة التقديم:

  1. اطلب إطارًا للصورة المتحركة.
  2. طلب البحث عن موضع الجهاز
  3. رسم المحتوى في موضع الجهاز استنادًا إلى موقعه
  4. عليك تنفيذ الإجراءات اللازمة لأجهزة الإدخال.
  5. كرِّر هذه الخطوات 60 مرة في الثانية إلى أن يقرِّر المستخدم المغادرة.

طلب إطار عرض

تحمل كلمة "إطار" عدة معانٍ في سياق Web XR. الأول هو إطار مرجعي يحدِّد المكان الذي يتم فيه حساب مصدر نظام الإحداثيات، وما يحدث لهذا المصدر عند تحريك الجهاز. (هل تظلّ الرؤية كما هي عندما يتحرك المستخدم أم تتغيّر كما يحدث في الحياة الحقيقية؟)

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

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

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
    // The time argument is for future use and not implemented at this time.
    // Process the frame.
    xrFrame.session.requestAnimationFrame(onFrame);
    }
});

الوضعيات

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

let pose = xrFrame.getDevicePose(xrFrameOfRef);
if (pose) {
    // Draw something to the screen.
}

المشاهدات

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

for (let view of xrFrame.views) {
    // Draw something to the screen.
}

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

حلقة العرض بالكامل

إذا جمعت كل هذه العناصر معًا، أحصل على الرمز أدناه. لقد تركت عنصر نائبًا ل devices الإدخال، وسأتناوله في قسم لاحق.

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
    // The time argument is for future use and not implemented at this time.
    let pose = xrFrame.getDevicePose(xrFrameOfRef);
    if (pose) {
        for (let view of xrFrame.views) {
        // Draw something to the screen.
        }
    }
    // Input device code will go here.
    frame.session.requestAnimationFrame(onFrame);
    }
}

إنهاء جلسة XR

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

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Create a WebGL layer and initialize the render loop.
    xrSession.addEventListener('end', onSessionEnd);
});

// Restore the page to normal after immersive access has been released.
function onSessionEnd() {
    xrSession = null;

    // Ending the session stops executing callbacks passed to the XRSession's
    // requestAnimationFrame(). To continue rendering, use the window's
    // requestAnimationFrame() function.
    window.requestAnimationFrame(onDrawFrame);
}

كيف يعمل التفاعل؟

كما هو الحال مع مدة صلاحية التطبيق، سأقدّم لك لمحة عن كيفية التفاعل مع الكائنات في الواقع المعزّز أو الواقع الافتراضي.

تعتمد واجهة برمجة التطبيقات WebXR Device API أسلوب "النقطة والنقر" لإدخال المستخدم. باستخدام هذا النهج، يحتوي كل مصدر إدخال على شعاع مؤشر محدّد للإشارة إلى مكان توجيه جهاز الإدخال والأحداث للإشارة إلى وقت اختيار عنصر معيّن. يرسم تطبيقك شعاع المؤشر ويعرض المكان الذي يشير إليه. عندما ينقر المستخدم على جهاز الإدخال، يتم تنشيط الأحداث - select وselectStart وselectEnd على وجه التحديد. يحدِّد تطبيقك ما تم النقر عليه ويستجيب له بشكل مناسب.

جهاز الإدخال وشعاع المؤشر

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

let inputSources = xrSession.getInputSources();
for (let xrInputSource of inputSources) {
    let inputPose = frame.getInputPose(inputSource, xrFrameOfRef);
    if (!inputPose) {
    continue;
    }
    if (inputPose.gripMatrix) {
    // Render a virtual version of the input device
    //   at the correct position and orientation.
    }
    if (inputPose.pointerMatrix) {
    // Draw a ray from the gripMatrix to the pointerMatrix.
    }
}

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

اختيار عناصر في المساحة الافتراضية

إنّ مجرد الإشارة إلى الأشياء في الواقع المعزّز/الواقع الافتراضي لا فائدة منه. للقيام بأي شيء مفيد، يحتاج المستخدمون إلى القدرة على تحديد الأشياء. توفّر WebXR Device API ثلاثة أحداث للردّ على تفاعلات المستخدمين: select وselectStart و selectEnd. هناك مشكلة لم أتوقعها: لا يُعلمك التطبيق إلا بنقرة على أحد أجهزة الإدخال. ولا تُعلمك هذه الرسائل بالعنصر الذي تم النقر عليه في البيئة. تتم إضافة عناصر معالجة الأحداث إلى كائن XRSession ويجب إضافتها فور توفّرها.

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Create a WebGL layer and initialize the render loop.
    xrSession.addEventListener('selectstart', onSelectStart);
    xrSession.addEventListener('selectend', onSelectEnd);
    xrSession.addEventListener('select', onSelect);
});

يستند هذا الرمز إلى مثال على اختيار الإدخال ، إذا كنت تريد المزيد من السياق.

لمعرفة ما تم النقر عليه، يمكنك استخدام وضع. (هل تتفاجأ؟ لم أكن أعتقد ذلك). ترتبط تفاصيل ذلك بتطبيقك أو أي إطار عمل تستخدمه، وبالتالي فهي خارج نطاق هذه المقالة. يوجد نهج Cottontail في مثال تحديد الإدخال.

function onSelect(ev) {
    let inputPose = ev.frame.getInputPose(ev.inputSource, xrFrameOfRef);
    if (!inputPose) {
    return;
    }
    if (inputPose.pointerMatrix) {
    // Figure out what was clicked and respond.
    }
}

الخاتمة: النظر إلى الأمام

كما ذكرت سابقًا، من المتوقّع أن تتوفّر تقنية الواقع المعزّز في الإصدار 69 من Chrome (الإصدار Canary في وقت ما في حزيران/يونيو 2018). مع ذلك، ننصحك بتجربة ما لدينا حتى الآن. لذلك، نحتاج إلى معرفة ملاحظاتك لتحسينها. يمكنك تتبُّع مستوى تقدّم الميزة من خلال الانتقال إلى ChromeStatus.com للاطّلاع على اختبار WebXR لذوي الاحتياجات الخاصة . يمكنك أيضًا اتّباع WebXR Anchors التي ستُحسِّن من تتبُّع الوضع.