פיתוח אפליקציה של מציאות רבודה (AR) באמצעות WebXR Device API

1. לפני שמתחילים

ב-Codelab הזה תלמדו איך ליצור אפליקציית אינטרנט של מציאות רבודה. נעשה שימוש ב-JavaScript כדי לרנדר מודלים תלת-ממדיים שנראים כאילו הם קיימים בעולם האמיתי.

אתם משתמשים ב-WebXR Device API שמשלב פונקציות של מציאות רבודה (AR) ומציאות מדומה (VR). אתם מתמקדים בתוספי AR ל-WebXR Device API כדי ליצור אפליקציית AR פשוטה שפועלת באינטרנט האינטראקטיבי.

מה זה AR?

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

השימוש במציאות רבודה (AR) באפליקציות הפך לנפוץ אחרי ש-Google השיקה את ARCore ו-Apple השיקה את ARKit. השימוש במציאות רבודה באפליקציות נעשה למגוון מטרות, כמו מסנני סלפי או משחקים מבוססי מציאות רבודה.

מה תפַתחו

ב-Codelab הזה תבנו אפליקציית אינטרנט שמציבה מודל בעולם האמיתי באמצעות מציאות רבודה. האפליקציה שלכם:

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

מה תלמדו

  • איך משתמשים ב-WebXR Device API
  • איך מגדירים סצנת AR בסיסית
  • איך מוצאים משטח באמצעות בדיקות פגיעה ב-AR
  • איך טוענים ומעבדים מודל תלת-ממד שמסונכרן עם פיד המצלמה בעולם האמיתי
  • איך מעבדים צללים על סמך המודל התלת-ממדי

ה-Codelab הזה מתמקד בממשקי API של AR. מושגים ובלוקים של קוד שלא רלוונטיים מוצגים בקצרה, ואתם יכולים למצוא אותם בקוד המאגר המתאים.

הדרישות

במכשיר ה-AR, לוחצים על Try it (אפשר לנסות) כדי לנסות את השלב הראשון של ה-codelab הזה. אם מוצג דף עם ההודעה 'בדפדפן שלך אין תכונות של מציאות רבודה', צריך לבדוק אם שירותי Google Play למציאות רבודה מותקנים במכשיר Android.

2. הגדרת סביבת הפיתוח

הורדת הקוד

  1. כדי להוריד את כל הקוד של ה-Codelab הזה לתחנת העבודה, לוחצים על הקישור הבא:

  1. מחלצים את קובץ ה-ZIP שהורד. הפעולה הזו תפרוס תיקיית בסיס (ar-with-webxr-master) שמכילה ספריות של כמה שלבים ב-Codelab הזה, יחד עם כל המשאבים שאתם צריכים.

התיקיות step-03 ו-step-04 מכילות את מצב הסיום הרצוי של השלבים השלישי והרביעי של ה-codelab הזה, וגם את התוצאה final. הן מופיעות שם לצורך השוואה.

כל עבודת הקידוד מתבצעת בספרייה work.

התקנה של שרת אינטרנט

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

  1. אחרי שמתקינים את אפליקציית Web Server for Chrome, עוברים אל chrome://apps ולוחצים על סמל שרת האינטרנט:

סמל של שרת אינטרנט

אחרי זה תופיע תיבת הדו-שיח הזו, שבה אפשר להגדיר את שרת האינטרנט המקומי:

הגדרת שרת אינטרנט של Chrome

  1. לוחצים על בחירת תיקייה ובוחרים בתיקייה ar-with-webxr-master. כך תוכלו להציג את העבודה שלכם בתהליך דרך כתובת ה-URL שמודגשת בתיבת הדו-שיח של שרת האינטרנט (בקטע כתובות ה-URL של שרת האינטרנט).
  2. בקטע Options (needs restart) (אפשרויות (נדרשת הפעלה מחדש)), מסמנים את התיבה Automatically show index.html (הצגה אוטומטית של index.html).
  3. מעבירים את המתג של שרת אינטרנט למצב הפסקה ואז בחזרה למצב התחלה.הפעלה מחדש של שרת האינטרנט של Chrome
  4. מוודאים שמופיעה לפחות כתובת URL אחת של שרת אינטרנט: http://127.0.0.1:8887 – כתובת ה-URL של localhost שמוגדרת כברירת מחדל.

הגדרת העברה ליציאה אחרת

מגדירים את מכשיר ה-AR כך שכאשר נכנסים ל-localhost:8887 במכשיר, הוא ניגש לאותה יציאה בתחנת העבודה.

  1. בתחנת העבודה של הפיתוח, עוברים אל chrome://inspect ולוחצים על העברת יציאות...: chrome://inspect
  2. משתמשים בתיבת הדו-שיח Port forwarding settings (הגדרות העברה ליציאה אחרת) כדי להעביר את יציאה 8887 אל localhost:8887.
  3. מסמנים את תיבת הסימון הפעלת העברת פורטים:

הגדרת העברה ליציאה אחרת

אימות ההגדרה

בודקים את החיבור:

  1. מחברים את מכשיר ה-AR לתחנת העבודה באמצעות כבל USB.
  2. במכשיר ה-AR ב-Chrome, מזינים http://localhost:8887 בסרגל הכתובות. מכשיר ה-AR צריך להעביר את הבקשה הזו לשרת האינטרנט של תחנת העבודה לפיתוח. אמורה להופיע רשימה של קבצים.
  3. במכשיר ה-AR, לוחצים על step-03 כדי לטעון את קובץ step-03/index.html בדפדפן.

אמור להופיע דף עם הלחצן התחלת מציאות רבודה.

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

יש תמיכה ב-ARCore

אין תמיכה ב-ARCore

החיבור לשרת האינטרנט אמור לפעול עכשיו עם מכשיר ה-AR.

  1. לוחצים על מעבר למצב מציאות רבודה. יכול להיות שתתבקשו להתקין את ARCore.

ההצעה להתקנת ARCore

בפעם הראשונה שמפעילים אפליקציית AR, מוצגת בקשה להעניק הרשאות גישה למצלמה.

בקשת הרשאות גישה למצלמה ב-Chromeתיבת דו-שיח של הרשאות

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

3. הגדרת WebXR

בשלב הזה נסביר איך להגדיר סשן WebXR וסצנת AR בסיסית. דף ה-HTML מסופק עם סגנון CSS ו-JavaScript להפעלת פונקציונליות בסיסית של AR. כך תהליך ההגדרה מהיר יותר, וה-codelab יכול להתמקד בתכונות של AR.

דף ה-HTML

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

כדי להפעיל תכונות AR, צריך לבצע פעולת משתמש. לכן יש כמה רכיבי Material Design להצגת הלחצן הפעלת AR וההודעה על דפדפן לא נתמך.

קובץ index.html שכבר נמצא בספרייה work אמור להיראות בערך כך. זהו קטע קוד חלקי בלבד, אל תעתיקו אותו לקובץ שלכם!

<!-- Don't copy this code into your file! -->
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Building an augmented reality application with the WebXR Device API</title>
    <link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css">
    <script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>

    <!-- three.js -->
    <script src="https://unpkg.com/three@0.123.0/build/three.js"></script>
    <script src="https://unpkg.com/three@0.123.0/examples/js/loaders/GLTFLoader.js"></script>

    <script src="../shared/utils.js"></script>
    <script src="app.js"></script>
  </head>
  <body>
  <!-- Information about AR removed for brevity. -->

  <!-- Starting an immersive WebXR session requires user interaction. Start the WebXR experience with a simple button. -->
  <a onclick="activateXR()" class="mdc-button mdc-button--raised mdc-button--accent">
    Start augmented reality
  </a>

</body>
</html>

פתיחת קוד ה-JavaScript של המפתח

נקודת ההתחלה של האפליקציה שלך היא בapp.js. הקובץ הזה מספק קוד boilerplate להגדרת חוויית AR.

ספריית העבודה שלכם כבר כוללת את קוד האפליקציה (app.js).

בדיקה אם יש תמיכה ב-WebXR וב-AR

כדי שמשתמש יוכל לעבוד עם AR, צריך לבדוק אם קיימת התכונה navigator.xr ואם קיימות תכונות ה-XR הנדרשות. אובייקט navigator.xr הוא נקודת הכניסה ל-WebXR Device API, ולכן הוא צריך להתקיים אם המכשיר תואם. כדאי גם לבדוק אם יש תמיכה במצב הסשן "immersive-ar".

אם הכול תקין, כשלוחצים על הלחצן כניסה למציאות רבודה המערכת מנסה ליצור סשן XR. אחרת, מתבצעת קריאה ל-onNoXRDevice() (ב-shared/utils.js) שבה מוצגת הודעה על כך שאין תמיכה ב-AR.

הקוד הזה כבר קיים ב-app.js, כך שלא צריך לבצע שינוי.

(async function() {
  if (navigator.xr && await navigator.xr.isSessionSupported("immersive-ar")) {
    document.getElementById("enter-ar").addEventListener("click", activateXR)
  } else {
    onNoXRDevice();
  }
})();

שליחת בקשה לXRSession

כשלוחצים על Enter augmented Reality (כניסה למציאות רבודה), הקוד קורא ל-activateXR(). כך מתחילים את חוויית ה-AR.

  1. מאתרים את הפונקציה activateXR() ב-app.js. חלק מהקוד לא נכלל:
activateXR = async () => {
  // Initialize a WebXR session using "immersive-ar".
  this.xrSession = /* TODO */;

  // Omitted for brevity
}

נקודת הכניסה ל-WebXR היא דרך XRSystem.requestSession(). משתמשים במצב immersive-ar כדי לאפשר צפייה בתוכן שעבר רינדור בסביבה של העולם האמיתי.

  1. מפעילים את this.xrSession באמצעות מצב "immersive-ar":
activateXR = async () => {
  // Initialize a WebXR session using "immersive-ar".
  this.xrSession = await navigator.xr.requestSession("immersive-ar");

  // ...
}

אתחול של XRReferenceSpace

XRReferenceSpace מתאר את מערכת הקואורדינטות שמשמשת לאובייקטים בעולם הווירטואלי. מצב 'local' מתאים במיוחד לחוויית מציאות רבודה, עם מרחב ייחוס שיש לו נקודת התחלה קרובה לצופה ומעקב יציב.

מאתחלים את this.localReferenceSpace ב-onSessionStarted() באמצעות הקוד הבא:

this.localReferenceSpace = await this.xrSession.requestReferenceSpace("local");

הגדרת אנימציה בלופ

  1. משתמשים ב-XRSession של requestAnimationFrame כדי להתחיל בלולאת רינדור, בדומה ל-window.requestAnimationFrame.

בכל פריים, הפונקציה onXRFrame נקראת עם חותמת זמן ועם XRFrame.

  1. משלימים את ההטמעה של onXRFrame. כשמציירים פריים, מוסיפים את הבקשה הבאה לתור על ידי הוספה של:
// Queue up the next draw request.
this.xrSession.requestAnimationFrame(this.onXRFrame);
  1. מוסיפים קוד כדי להגדיר את סביבת הגרפיקה. מוסיפים את הטקסט הבא לחלק התחתון של onXRFrame:
// Bind the graphics framebuffer to the baseLayer's framebuffer.
const framebuffer = this.xrSession.renderState.baseLayer.framebuffer;
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer);
this.renderer.setFramebuffer(framebuffer);
  1. כדי לקבוע את תנוחת הצופה, משתמשים ב-XRFrame.getViewerPose(). XRViewerPose הזה מתאר את המיקום והכיוון של המכשיר במרחב. הוא גם מכיל מערך של XRViews, שמתאר כל נקודת מבט שהסצנה צריכה להיות מעובדת ממנה כדי להציג אותה בצורה נכונה במכשיר הנוכחי. ל-VR סטריאוסקופי יש שני מבטים (אחד לכל עין), אבל למכשירי AR יש רק מבט אחד.
    המידע ב-pose.views משמש בדרך כלל להגדרת מטריצת התצוגה ומטריצת ההיטל של המצלמה הווירטואלית. הפעולה הזו משפיעה על הפריסה של הסצנה בתלת-ממד. אחרי שמגדירים את המצלמה, אפשר לעבד את הסצנה.
  2. מוסיפים את הטקסט הבא לחלק התחתון של onXRFrame:
// Retrieve the pose of the device.
// XRFrame.getViewerPose can return null while the session attempts to establish tracking.
const pose = frame.getViewerPose(this.localReferenceSpace);
if (pose) {
  // In mobile AR, we only have one view.
  const view = pose.views[0];

  const viewport = this.xrSession.renderState.baseLayer.getViewport(view);
  this.renderer.setSize(viewport.width, viewport.height);

  // Use the view's transform matrix and projection matrix to configure the THREE.camera.
  this.camera.matrix.fromArray(view.transform.matrix);
  this.camera.projectionMatrix.fromArray(view.projectionMatrix);
  this.camera.updateMatrixWorld(true);

  // Render the scene with THREE.WebGLRenderer.
  this.renderer.render(this.scene, this.camera);
}

אני רוצה לנסות

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

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

4. הוספת כוונת טירגוט

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

הסבר על בדיקה של מיקום המצביע

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

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

הסבר על בדיקה של מיקום המצביע

בקשה ל-XRSession עם תכונות נוספות

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

  1. בapp.js, מאתרים את navigator.xr.requestSession.
  2. מוסיפים את התכונות "hit-test" ו-"dom-overlay" כ-requiredFeatures באופן הבא:
this.xrSession = await navigator.xr.requestSession("immersive-ar", {
  requiredFeatures: ["hit-test", "dom-overlay"]
});
  1. מגדירים את שכבת העל של ה-DOM. מציבים את רכיב document.body מעל שידור מהמצלמה במציאות רבודה, כך:
this.xrSession = await navigator.xr.requestSession("immersive-ar", {
  requiredFeatures: ["hit-test", "dom-overlay"],
  domOverlay: { root: document.body }
});

הוספת הנחיה ליצירת תנועה

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

משתמשים ב"dom-overlay" מהשלב הקודם כדי להציג הנחיה ליצירת תמונה עם תנועה מעל הסטרימינג מהמצלמה.

הוספת <div> ל-index.html עם מזהה stabilization. האנימציה הזו <div> מוצגת למשתמשים כדי לייצג את סטטוס הייצוב, ומבקשת מהם להזיז את המכשיר כדי לשפר את תהליך ה-SLAM. ההודעה הזו מוצגת כשהמשתמש נמצא ב-AR ומוסתרת כשהכוונת מוצאת משטח. ההצגה וההסתרה נשלטות על ידי מחלקות <body>.

  <div id="stabilization"></div>

</body>
</html>

הוספת כוונת

שימוש בכוונת כדי לציין את המיקום שאליו מכוון שדה הראייה של המכשיר.

  1. ב-app.js, מחליפים את הקריאה DemoUtils.createCubeScene() ב-setupThreeJs() ב-Three.Scene() ריק.
setupThreeJs() {
  // ...

  // this.scene = DemoUtils.createCubeScene();
  this.scene = DemoUtils.createLitScene();
}
  1. מאכלסים את הסצנה החדשה באובייקט שמייצג את נקודת ההתנגשות. המחלקות Reticle שסופקו מטפלות בטעינת מודל הכוונת ב-shared/utils.js.
  2. מוסיפים את Reticle לסצנה ב-setupThreeJs():
setupThreeJs() {
  // ...

  // this.scene = DemoUtils.createCubeScene();
  this.scene = DemoUtils.createLitScene();
  this.reticle = new Reticle();
  this.scene.add(this.reticle);
}

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

  1. מוסיפים את הטקסט הבא לקובץ onSessionStarted() ב-app.js:
async onSessionStarted() {
  // ...

  // Setup an XRReferenceSpace using the "local" coordinate system.
  this.localReferenceSpace = await this.xrSession.requestReferenceSpace("local");

  // Add these lines:
  // Create another XRReferenceSpace that has the viewer as the origin.
  this.viewerSpace = await this.xrSession.requestReferenceSpace("viewer");
  // Perform hit testing using the viewer as origin.
  this.hitTestSource = await this.xrSession.requestHitTestSource({ space: this.viewerSpace });

  // ...
}
  1. באמצעות hitTestSource, מבצעים בדיקה של מיקום המצביע בכל פריים:
    • אם לא מוצגות תוצאות לבדיקה של מיקום המצביע, סימן שלא עבר מספיק זמן מאז ש-ARCore התחיל לנתח את הסביבה. במקרה כזה, צריך להנחות את המשתמש להזיז את המכשיר באמצעות מייצב התמונה <div>.
    • אם יש תוצאות, מעבירים את הכוונת למיקום הזה.
  2. כדי לשנות את onXRFrame ולהזיז את הכוונת:
onXRFrame = (time, frame) => {
  // ... some code omitted ...
  this.camera.updateMatrixWorld(true);

  // Add the following:
  const hitTestResults = frame.getHitTestResults(this.hitTestSource);

  if (!this.stabilized && hitTestResults.length > 0) {
    this.stabilized = true;
    document.body.classList.add("stabilized");
  }
  if (hitTestResults.length > 0) {
    const hitPose = hitTestResults[0].getPose(this.localReferenceSpace);

    // update the reticle position
    this.reticle.visible = true;
    this.reticle.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z)
    this.reticle.updateMatrixWorld(true);
  }
  // More code omitted.
}

הוספת התנהגות בהקשה על המסך

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

  1. מוסיפים event listener של select בתחתית של onSessionStarted:
this.xrSession.addEventListener("select", this.onSelect);

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

  1. יוצרים הטמעה של onSelect בכיתה App:
onSelect = () => {
  if (window.sunflower) {
    const clone = window.sunflower.clone();
    clone.position.copy(this.reticle.position);
    this.scene.add(clone);
  }
}

בדיקת האפליקציה

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

  1. כשמריצים את האפליקציה, אמורה להופיע כוונת שמשרטטת את פני השטח של הרצפה. אם לא, נסו להזיז את הטלפון לאט כדי להסתכל סביב.
  2. אחרי שרואים את הכוונת, מקישים עליה. יש להניח מעליו חמנית. יכול להיות שתצטרכו לזוז קצת כדי שפלטפורמת ה-AR הבסיסית תוכל לזהות טוב יותר משטחים בעולם האמיתי. תאורה חלשה ומשטחים ללא מאפיינים מפחיתים את איכות ההבנה של הסצנה ומגדילים את הסיכוי שלא יימצאו פגיעות. אם נתקלתם בבעיות, כדאי לעיין בקוד step-04/app.js כדי לראות דוגמה פעילה של השלב הזה.

5. הוספת צללים

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

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

  1. מפעילים את הצלליות ב-three.js WebGLRenderer. אחרי שיוצרים את רכיב ה-renderer, מגדירים את הערכים הבאים ב-shadowMap שלו:
setupThreeJs() {
  ...
  this.renderer = new THREE.WebGLRenderer(...);
  ...
  this.renderer.shadowMap.enabled = true;
  this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  ...
}

הסצנה לדוגמה שנוצרה ב-DemoUtils.createLitScene() מכילה אובייקט בשם shadowMesh, משטח שטוח ואופקי שרק מטיל צללים. המיקום הראשוני של המשטח הזה הוא Y‏ 10,000 יחידות. אחרי שממקמים חמנייה, מעבירים את shadowMesh לגובה זהה לגובה של פני השטח בעולם האמיתי, כך שהצל של הפרח יוצג מעל הקרקע בעולם האמיתי.

  1. ב-onSelect, אחרי שמוסיפים את clone לסצנה, מוסיפים קוד כדי לשנות את המיקום של מישור הצל:
onSelect = () => {
  if (window.sunflower) {
    const clone = window.sunflower.clone();
    clone.position.copy(this.reticle.position);
    this.scene.add(clone);

    const shadowMesh = this.scene.children.find(c => c.name === "shadowMesh");
    shadowMesh.position.y = clone.position.y;
  }
}

אני רוצה לנסות

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

6. מקורות מידע נוספים

מעולה! הגעתם לסוף של ה-codelab בנושא AR באמצעות WebXR.

מידע נוסף