الويب الغامر هو تجارب العالم الافتراضي التي يتم استضافتها من خلال المتصفّح. وظهرت تجارب الواقع الافتراضي هذه بالكامل في المتصفّح أو في سماعات الرأس المزوّدة بتقنية الواقع الافتراضي.
الويب الغامر هو تجارب العالم الافتراضي التي يتم استضافتها من خلال المتصفّح. ويشمل ذلك تجارب الواقع الافتراضي بالكامل التي تظهر في المتصفّح أو في سماعات الرأس المزوّدة بتقنية الواقع الافتراضي، مثل 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 ومرحلة تجربة وتقييم جديدة.
What happened to WebVR 1.1?
لقد تعلمنا الكثير من WebVR 1.1، ولكن مع مرور الوقت، تبيّن لنا أنّه يجب إجراء بعض التغييرات الرئيسية لتتوافق مع أنواع التطبيقات التي يريد المطوّرون إنشاؤها. إنّ القائمة الكاملة للدروس المستفادة طويلة جدًا لدرجة أنّه لا يمكننا الخوض فيها هنا، ولكنها تشمل مشاكل مثل ربط واجهة برمجة التطبيقات صراحةً بسلسلة JavaScript الأساسية، والعديد من الفرص التي تتيح للمطوّرين ضبط إعدادات خاطئة بشكل واضح، واستخدامات شائعة مثل أن تكون النافذة السحرية نتيجة جانبية بدلاً من ميزة مقصودة. (النافذة السحرية هي تقنية لعرض محتوى immersive بدون استخدام سماعة رأس، حيث يعرض التطبيق عرضًا واحدًا استنادًا إلى أداة استشعار الاتجاه في الجهاز).
يسهّل التصميم الجديد عمليات التنفيذ البسيطة وتحسينات كبيرة في الأداء. وفي الوقت نفسه، بدأت تقنية الواقع المعزّز وحالات الاستخدام الأخرى بالظهور، وأصبح من المهم أن تكون واجهة برمجة التطبيقات قابلة للتوسيع لتتيح استخدام هذه الحالات في المستقبل.
تم تصميم واجهة برمجة التطبيقات WebXR Device API وتسميتها مع وضع حالات الاستخدام الموسّعة هذه في الاعتبار، كما أنّها توفّر مسارًا أفضل للمضي قدمًا. تعهد مستخدمو WebVR بالانتقال إلى WebXR Device API.
ما هي WebXR Device API؟
مثل مواصفات WebVR السابقة، واجهة WebXR Device API هي منتج من مجموعة منتدى الويب الشامل التي تضم مساهمين من Google وMicrosoft وMozilla وغيرها. إنّ الحرف "X" في الواقع المعزّز هو متغيّر حسابي يشير إلى أيّ شيء في مجموعة التجارب الغامرة. يتوفّر هذا الإصدار في الإصدار التجريبي من الإصدار الأصلي المذكور سابقًا، بالإضافة إلى العناصر القابلة للتضمين.
عند نشر هذه المقالة في الأصل خلال فترة الإصدار التجريبي من Chrome 67، كانت فقط إمكانات الواقع الافتراضي مفعَّلة. تم توفير تقنية الواقع المعزّز في الإصدار 69 من Chrome. يمكنك الاطّلاع على المزيد من المعلومات عن ذلك في مقالة الواقع المعزّز على الويب.
هناك المزيد من المعلومات حول واجهة برمجة التطبيقات الجديدة هذه أكثر من تلك التي يمكنني ذكرها في مقالة مثل هذه. أريد أن أقدّم لك ما يكفي من المعلومات لفهم عيّنات WebXR. يمكنك الاطّلاع على مزيد من المعلومات في كلّ من الشرح المفصّلجه ودليلجه المخصّص للمستخدِمين الأوائل للويب الافتراضي. سأوسّع نطاق استخدام الميزة الأخيرة مع تقدّم الفترة التجريبية الأصلية. يُرجى عدم التردد في فتح المشاكل أو إرسال طلبات دمج.
في هذه المقالة، سأتناول بدء جلسة الواقع المعزّز وإيقافها وتشغيلها، بالإضافة إلى بعض الأساسيات حول معالجة الإدخال.
لن أتطرق إلى كيفية رسم محتوى الواقع المعزّز/VR على الشاشة. لا توفّر واجهة برمجة التطبيقات WebXR Device API ميزات عرض الصور. فالقرار يعود لك. يتم الرسم باستخدام واجهات برمجة تطبيقات WebGL. يمكنك إجراء ذلك إذا كنت طموحًا حقًا. مع ذلك، ننصحك باستخدام إطار عمل. تستخدم نماذج الويب الشاملة أحد نماذج الويب التي تم إنشاؤها خصيصًا للعروض التوضيحية والتي تُسمى Cottontail. تتيح مكتبة Three.js استخدام WebXR منذ شهر أيار (مايو). لم أسمع أي شيء عن A-Frame.
بدء تطبيق وتشغيله
في ما يلي العملية الأساسية:
- طلب جهاز XR
- اطلب جلسة واقع ممحوّر إذا كانت متاحة. إذا أردت من المستخدم وضع هاتفه في سماعة رأس، تُعرف هذه الجلسة باسم "جلسة غامرّة" وتتطلّب من المستخدم إجراء إيماءة للدخول.
- استخدِم الجلسة لتشغيل حلقة عرض توفّر 60 إطارًا للصورة في الثانية. ارسم المحتوى المناسب على الشاشة في كل إطار.
- يمكنك تشغيل حلقة التقديم إلى أن يقرر المستخدم الخروج.
- إنهاء جلسة الواقع المعزّز
لنلقِ نظرة على ذلك بمزيد من التفصيل ونضيف بعض الرموز البرمجية. لن تتمكّن من تشغيل تطبيق من خلال ما سأعرضه لك. ولكن مرة أخرى، هذا مجرد لمحة عن ذلك.
طلب جهاز الواقع الممتد
ستتعرّف هنا على رمز رصد العناصر العادي. يمكنك تضمين هذا الرمز
في دالة باسم 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
})
تشغيل حلقة التقديم
يتطلّب رمز هذه الخطوة بعض التفسير. سأطرح عليك مجموعة من الكلمات لفهم المشكلة. إذا أردت إلقاء نظرة على الرمز النهائي، يمكنك الانتقال إلى الخطوة التالية للاطّلاع عليه سريعًا ثم العودة للاطّلاع على التفسير الكامل. هناك الكثير من المعلومات التي قد لا تتمكّن من استنتاجها.
في ما يلي العملية الأساسية لحلقة التقديم:
- اطلب إطارًا للصورة المتحركة.
- طلب معلومات عن موضع الجهاز
- رسم المحتوى في موضع الجهاز استنادًا إلى موقعه
- عليك إجراء العمل المطلوب على أجهزة الإدخال.
- كرِّر ذلك 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
كمصفوفة. إذا كنت في
جلسة غير غامرة، يحتوي الصفيف على عرض واحد. إذا كنت في جلسة immersive
، تحتوي الصفيف على صفيفَين، أحدهما لكل عين.
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);
}
}
إنهاء جلسة الواقع المعزّز
قد تنتهي جلسة الواقع المعزّز لعدة أسباب، بما في ذلك إنهاء الجلسة من خلال رمزك الخاص
من خلال طلب إلى XRSession.end()
. وتشمل الأسباب الأخرى عدم اتصال السماعتين
بالجهاز أو سيطرة تطبيق آخر عليهما. لهذا السبب، يجب أن يراقب
التطبيق المُمتثل للسياسات حدث الانتهاء، وعند حدوثه،
يُرجى تجاهل الجلسة وعناصر أداة التحويل. لا يمكن
استئناف جلسة الواقع المعزّز بعد انتهائها.
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 التي ستُحسِّن من تتبُّع الوضع.