ברוכים הבאים לאינטרנט העשיר

רשת האינטרנט העשירה היא חוויות של עולם וירטואלי שמתארחות בדפדפן. כל החוויה הזו של המציאות הווירטואלית מוצגת בדפדפן או במשקפי VR שתומכים ב-VR.

Joe Medley
Joe Medley

רשת האינטרנט העשירה היא חוויות של עולם וירטואלי שמתארחות בדפדפן. התוכן הזה כולל את כל חוויות המציאות המדומה שמוצגות בדפדפן או במשקפי VR שתומכים ב-VR, כמו Daydream, Oculus Rift, Samsung Gear VR, HTC Vive ו-Windows Mixed Reality Headsets, וגם חוויות מציאות רבודה שפותחו עבור מכשירים ניידים עם תמיכה ב-AR.

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

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

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

איך ניתן להגיע לשם?

האינטרנט העשיר זמין כבר כמעט שנה בפורמט עוברי. הפעולה הזו התבצעה באמצעות WebVR 1.1 API, שהיה זמין בגרסת מקור לניסיון מאז Chrome 62. ה-API הזה נתמך גם ב-Firefox וב-Edge, וגם ב-Polyfill עבור Safari.

אבל הגיע הזמן להתקדם.

תקופת הניסיון המקורית הסתיימה ב-24 ביולי 2018, והמפרט של WebXR Device API הוחלף על ידי גרסת מקור חדשה לניסיון.

מה קרה ל-WebVR 1.1?

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

העיצוב החדש מאפשר הטמעות פשוטות יותר ושיפורי ביצועים גדולים. במקביל, התחלנו לפתח את המציאות הרבודה (AR) ותרחישים אחרים לדוגמה, ועכשיו היה חשוב להרחיב את ה-API כך שיתמוך בהם בעתיד.

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

מה זה WebXR Device API?

כמו המפרט של WebVR, ה-WebXR Device API הוא מוצר של קבוצת הקהילה Immersive Web Community שכוללת משתתפים מ-Google, Microsoft, Mozilla וחברות אחרות. הפונקציה X ב-XR נועדה להיות סוג של משתנה אלגברי שמייצג כל דבר במגוון של חוויות תלת-ממדיות. הוא זמין בגרסת המקור לניסיון שהוזכרה קודם, וגם באמצעות polyfill.

כשמאמר זה פורסם במקור במהלך תקופת הבטא של Chrome 67, הופעלו רק יכולות VR. מציאות רבודה הגיעה ל-Chrome 69. תוכלו לקרוא עליו במציאות רבודה באינטרנט.

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

במאמר הזה אדבר על התחלה, הפסקה והפעלה של הפעלת XR, וגם כמה פרטים בסיסיים על עיבוד קלט.

אני לא מתכוון להסביר איך לצייר תוכן AR/VR במסך. ה-WebXR Device API לא מספק תכונות של עיבוד תמונות. זה תלוי בך. השרטוט מתבצע באמצעות ממשקי API של WebGL. אתם יכולים לעשות את זה אם אתם ממש שאפתניים. עם זאת, אנחנו ממליצים להשתמש במסגרת. בדוגמאות האינטרנט העשירות נעשה שימוש במופע אחד שנוצר במיוחד להדגמות שנקראות Cottontail. Three.js תומך ב-WebXR מאז מאי. לא שמעתי דבר על A-Frame.

הפעלה והפעלה של אפליקציה

התהליך הבסיסי הוא:

  1. בקש מכשיר XR.
  2. אם היא זמינה, תוכלו לבקש סשן XR. אם רוצים שהמשתמש יכניס את הטלפון שלו לאוזניות, זה נקרא 'סשן עשיר' שמחייב כניסת משתמש.
  3. השתמשו בסשן כדי להריץ לולאת עיבוד שמספקת 60 פריימים של תמונה לשנייה. משרטטים תוכן מתאים למסך בכל מסגרת.
  4. מפעילים את לולאת העיבוד עד שהמשתמש מחליט לצאת.
  5. לסיים את הפעלת ה-XR.

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

בקשה למכשיר XR

כאן אפשר לזהות את הקוד הרגיל לזיהוי תכונות. אפשר לכלול אותו בפונקציה בשם 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.");
}

בקשה לפגישת XR

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

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 פעמים בשנייה עד שהמשתמש מחליט לצאת.

בקשה למסגרת למצגת

למילה 'frame' יש כמה משמעויות בהקשר של Web XR. הראשונה היא מסגרת ההפניה שקובעת מאיפה מחושב מקור מערכת הקואורדינטות ומה קורה למקור הזה כשהמכשיר זז. (האם התצוגה נשארת ללא שינוי כאשר המשתמש זז או משתנה כמו במציאות?)

הסוג השני של המסגרת הוא מסגרת המצגת, שמיוצגת על ידי אובייקט XRFrame. האובייקט מכיל את המידע הנדרש כדי לעבד למכשיר פריים אחד של תמונת AR/VR. זה קצת מבלבל כי מסגרת של מצגת מאוחזרת על ידי קריאה ל-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);
    }
});

תנוחות

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

כל לולאת העיבוד

אם ארכיב את כל זה ביחד, אקבל את הקוד הבא. השארתי placeholder עבור התקני הקלט, אותו נעסוק בקטע מאוחר יותר.

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

סשן 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);
}

איך עובדת האינטראקציה?

בדומה למשך החיים של האפליקציה, אני אתן לכם טעימה מאינטראקציה עם אובייקטים ב-AR או VR.

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

מכשיר הקלט וקרן המצביע

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

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.
    }
}

זוהי גרסה מקוצרת של הדוגמה למעקב אחר קלט מקבוצת Immersive Web Community. כמו בעיבוד פריים, גם אתם יכולים לצייר קרניים והמכשיר תלוי בכם. כפי שציינו קודם, צריך להריץ את הקוד הזה כחלק מלולאת העיבוד.

בחירת פריטים במרחב הווירטואלי

הצבעה על דברים ב-AR/VR לא מועילה במיוחד. כדי לעשות משהו מועיל, המשתמשים צריכים את היכולת לבחור. 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.
    }
}

סיכום: במבט קדימה

כפי שאמרתי קודם, מציאות רבודה צפויה להיות ב-Chrome 69 (Canary מתישהו ביוני 2018). עם זאת, אני ממליץ לך לנסות את מה שעשינו עד עכשיו. אנחנו צריכים משוב כדי לשפר אותו. תוכלו לצפות בהתקדמות הזו על ידי צפייה ב-ChromeStatus.com ב-WebXR Hit Test. אפשר גם לעקוב אחרי WebXR anchors כדי לשפר את המעקב אחרי תנוחות.