המציאות הווירטואלית מגיעה לאינטרנט

כמה מושגים בסיסיים שיעזרו לכם להתכונן למגוון חוויות immersive: מציאות מדומה, מציאות רבודה וכל מה שביניהם.

Joe Medley
Joe Medley

חוויית שימוש מעמיקה הגיעה לאינטרנט בגרסה 79 של Chrome. WebXR Device API מאפשר לכם להשתמש במציאות מדומה, ותמיכה במציאות רבודה תגיע ב-Chrome 81. עדכון ל-GamePad API מרחיב את השימוש המתקדם באמצעי הבקרה ל-VR. בקרוב תהיה תמיכה במפרטים האלה בדפדפנים נוספים, כולל Firefox Reality, ‏ Oculus Browser, ‏ Edge ודפדפן Helio של Magic Leap, בין היתר.

המאמר הזה הוא הראשון בסדרה בנושא האינטרנט העשיר. בחלק הזה נסביר איך מגדירים אפליקציית WebXR בסיסית, ואיך נכנסים ויוצאים מסשן XR. במאמרים הבאים נסקור את לולאת המסגרות (הכלי העיקרי לחוויית WebXR), את המאפיינים הספציפיים של המציאות הרבודה ואת WebXR Hit Test API, דרך לזיהוי משטחים בסשן AR. אלא אם צוין אחרת, כל מה שאציג במאמר הזה ובמאמרים הבאים רלוונטי גם ל-AR וגם ל-VR.

מהו האינטרנט העשיר?

אנחנו משתמשים בשני מונחים כדי לתאר חוויות immersive – מציאות מוגברת ומציאות וירטואלית – אבל רבים מתייחסים אליהם כאל ספקטרום שנע ממציאות מלאה ועד לווירטואליות מלאה, עם רמות שונות של חוויית immersive באמצע. האות X ב-XR מייצגת משתנה אלגברי שמייצג כל דבר בספקטרום של חוויות immersive.

תרשים שממחיש את הספקטרום של חוויות חזותיות, החל ממציאות מלאה ועד לחוויה סוחפת לחלוטין.
הספקטרום של חוויות עשירות וסוחפות

דוגמאות לחוויות סוחפות:

  • משחקים
  • סרטוני וידאו ב-360 מעלות
  • סרטונים דו-ממדיים (או תלת-ממדיים) מסורתיים שמוגשים בסביבה סוחפת
  • רכישת בית
  • הצגת מוצרים בבית לפני הרכישה
  • אומנות סוחפת
  • משהו מגניב שאף אחד עדיין לא חשב עליו

מושגים ושימוש

אסביר כמה יסודות של השימוש ב-WebXR Device API. אם אתם רוצים לקבל מידע מעמיק יותר, תוכלו לעיין בטעימות WebXR של קבוצת העבודה של האינטרנט העשיר או בחומרים המפורטים ההולכים וגדלים של MDN. אם אתם מכירים גרסאות מוקדמות של WebXR Device API, כדאי לעיין בכל החומר הזה. בוצעו שינויים.

הקוד במאמר הזה מבוסס על דוגמה בסיסית של קבוצת העבודה של האינטרנט העשיר (הדגמה, מקור), אבל עבר עריכה כדי לשפר את הבהירות והפשטות שלו.

חלק מהיצירה של מפרט WebXR היה פיתוח של אמצעי אבטחה ופרטיות כדי להגן על המשתמשים. לכן, ההטמעות חייבות לעמוד בדרישות מסוימות. דף אינטרנט או אפליקציה צריכים להיות פעילים ומוקדשים לפני שהם יכולים לבקש מהצופה מידע אישי רגיש. דפי אינטרנט או אפליקציות חייבים להופיע באמצעות HTTPS. ממשק ה-API עצמו נועד להגן על המידע שמתקבל מהחיישנים והמצלמות, והוא נחוץ לו כדי לפעול.

שליחת בקשה לפגישה

כדי להיכנס לסשן XR, נדרשת תנועת משתמש. כדי לעשות זאת, משתמשים בזיהוי המאפיינים כדי לבדוק אם XRSystem פועל (דרך navigator.xr) ומבצעים קריאה ל-XRSystem.isSessionSupported(). חשוב לזכור שבגרסאות 79 ו-80 של Chrome, האובייקט XRSystem נקרא XR.

בדוגמה הבאה, ציינתי שאני רוצה סשן מציאות מדומה עם סוג הסשן 'immersive-vr'. סוגי הסשנים האחרים הם 'immersive-ar' ו-'inline'. סשן בקוד מיועד להצגת תוכן בתוך HTML, והוא משמש בעיקר לתוכן טיזר. הדוגמה סשן AR immersive ממחישה זאת. אסביר את זה במאמר מאוחר יותר.

אחרי שאדע שהאתר תומך בסשנים של מציאות מדומה, אפעיל לחצן שמאפשר לי לקבל תנועת משתמש.

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. בגרסאות מוקדמות של ה-API, סקריפט היה צריך לבקש מכשיר לפני ששלח בקשה לסשן. עכשיו המכשיר נרכש באופן משתמע.

כניסה לסשן

אחרי קבלת סשן, צריך להתחיל אותו ולהיכנס אליו. אבל קודם כול, אצטרך להגדיר כמה דברים. כדי שאפשר יהיה לאפס את האפליקציה או דף האינטרנט כשהמשתמש יוצא מהם, צריך להגדיר גורם מטפל באירועים מסוג 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(). זהו תחילת הצגת התוכן הווירטואלי, שמתבצע במעגל המסגרות.

הרצת לולאה של פריימים

לולאת המסגרות היא לולאה אינסופית שנשלטת על ידי סוכן המשתמש, שבה התוכן מצויר שוב ושוב במסך. התוכן מצויר בבלוקים נפרדים שנקראים פריימים. רצף המסגרות יוצר את האשליה של תנועה. באפליקציות VR, קצב הפריימים לשנייה יכול לנוע בין 60 ל-144. התכונה 'מציאות מדומה ל-Android' פועלת במהירות של 30 פריימים לשנייה. הקוד לא צריך להניח שום קצב פריימים ספציפי.

התהליך הבסיסי של לולאת הפריימים הוא:

  1. התקשרו אל XRSession.requestAnimationFrame(). בתגובה, סוכן המשתמש מפעיל את XRFrameRequestCallback, שהגדרתם.
  2. בתוך פונקציית הקריאה החוזרת:
    1. התקשרו שוב למספר XRSession.requestAnimationFrame().
    2. אחזור של תנוחת הצופה.
    3. מעבירים ('מקשרים') את WebGLFramebuffer מה-XRWebGLLayer אל ה-WebGLRenderingContext.
    4. מריצים איטרציה על כל אובייקט XRView, מאחזרים את ה-XRViewport שלו מה-XRWebGLLayer ומעבירים אותו ל-WebGLRenderingContext.
    5. ציור משהו ב-framebuffer.

בהמשך המאמר נסביר על שלב 1 ועל חלק משלב 2, קרי הגדרה של XRFrameRequestCallback והפעלה שלו. הפריטים הנותרים בשלב 2 מפורטים בחלק השני.

XRFrameRequestCallback

אתם קובעים את הערך של XRFrameRequestCallback. הוא מקבל שני פרמטרים: DOMHighResTimeStamp ומופע של XRFrame. האובייקט XRFrame מספק את המידע הנדרש כדי ליצור רינדור של פריים אחד במסך. הארגומנט DOMHighResTimeStamp מיועד לשימוש עתידי.

לפני שאעשה משהו אחר, אבקש את הפריים הבא של האנימציה. כפי שצוין קודם, התזמון של הפריימים נקבע על ידי סוכן המשתמש על סמך החומרה הבסיסית. שליחת הבקשה לפריים הבא קודם מבטיחה שהמחזור של הפריים ימשיך אם משהו במהלך קריאת החזרה (callback) יגרום להצגת שגיאה.

function onXRFrame(hrTime, xrFrame) {
  let xrSession
= xrFrame.session;
  xrSession
.requestAnimationFrame(onXRFrame);
 
// Render a frame.
}

בשלב הזה, הגיע הזמן לצייר משהו לצופים. זה נושא לדיון בחלק השני. לפני שנמשיך, אראה לך איך לסיים סשן.

סיום הסשן

סשן immersive יכול להסתיים מכמה סיבות, כולל סיום על ידי הקוד שלכם באמצעות קריאה ל-XRSession.end(). סיבות אחרות יכולות להיות שהאוזניות לא מחוברות או שאפליקציה אחרת מפעילה אותן. לכן, אפליקציה שפועלת בצורה תקינה צריכה לעקוב אחרי האירוע end. במקרה כזה, צריך לבטל את הסשן ואת אובייקטי הרינדור שקשורים אליו. אי אפשר להמשיך סשן immersive שהסתיים. כדי לחזור לחוויה העוטפת, האפליקציה שלי צריכה להתחיל סשן חדש.

בכניסה לסשן הזכרתי שבמהלך ההגדרה הוספתי טיפול באירוע onend.

function onSessionStarted(xrSession) {
  xrSession
.addEventListener('end', onSessionEnded);
 
// More setup…
}

בתוך פונקציית הטיפול באירוע, משחזרים את המצב של האפליקציה לפני שהמשתמש נכנס לסשן.

function onSessionEnded(event) {
  xrSession
= null;
  xrButton
.textContent = 'Enter VR';
}

סיכום

לא הסברתי את כל מה שצריך כדי לכתוב אפליקציית Web XR או AR. אני מקווה שהסברתי מספיק כדי שתוכלו להתחיל להבין את הקוד בעצמכם, וגם מספיק כדי שתוכלו להתחיל להתנסות. במאמר הבא אסביר על לולאת המסגרות, שבה התוכן מצויר על המסך.

תמונה של JESHOOTS.COM ב-Unsplash