สร้างแอป Augmented Reality (AR) โดยใช้ WebXR Device API

1. ก่อนเริ่มต้น

โค้ดแล็บนี้จะแสดงตัวอย่างการสร้างเว็บแอป AR โดยใช้ JavaScript เพื่อแสดงผลโมเดล 3 มิติให้ดูเหมือนว่ามีอยู่จริงในโลก

คุณใช้ WebXR Device API ที่รวมฟังก์ชันการทำงาน AR และ Virtual Reality (VR) คุณเน้นการใช้ส่วนขยาย AR ใน WebXR Device API เพื่อสร้างแอป AR ที่ใช้งานง่ายให้ทำงานบนเว็บแบบอินเทอร์แอกทีฟ

AR คืออะไร

AR เป็นคําที่ใช้อธิบายการผสมผสานกราฟิกที่สร้างด้วยคอมพิวเตอร์เข้ากับโลกแห่งความเป็นจริง ในกรณีของ AR บนโทรศัพท์ หมายความว่าการวางกราฟิกคอมพิวเตอร์บนฟีดกล้องสดอย่างสมจริง อุปกรณ์ที่พร้อมใช้งาน AR จำเป็นต้องเข้าใจโลกที่อุปกรณ์กำลังเคลื่อนที่ผ่านและกำหนดท่าทาง (ตำแหน่งและการวางแนว) ของอุปกรณ์ในอวกาศ 3 มิติ เพื่อให้เอฟเฟกต์นี้ดูสมจริงอยู่เสมอเมื่อโทรศัพท์เคลื่อนที่ไปรอบๆ ซึ่งอาจรวมถึงการตรวจหาพื้นผิวและการประมาณแสงของสภาพแวดล้อม

AR ได้รับความนิยมอย่างแพร่หลายในแอปหลังจากการเปิดตัว ARCore ของ Google และ ARKit ของ Apple ไม่ว่าจะเป็นการใช้กับฟิลเตอร์เซลฟีหรือเกมที่ใช้ AR

สิ่งที่คุณจะสร้าง

ใน Codelab นี้ คุณจะได้สร้างเว็บแอปที่วางโมเดลในโลกจริงโดยใช้ Augmented Reality แอปของคุณจะทำสิ่งต่อไปนี้

  1. ใช้เซ็นเซอร์ของอุปกรณ์เป้าหมายเพื่อระบุและติดตามตำแหน่งและการวางแนวของอุปกรณ์ในโลก
  2. เรนเดอร์โมเดล 3 มิติที่วางซ้อนบนมุมมองกล้องสด
  3. ทำการทดสอบการชนเพื่อวางวัตถุบนพื้นผิวที่ค้นพบในโลกแห่งความเป็นจริง

สิ่งที่คุณจะได้เรียนรู้

  • วิธีใช้ WebXR Device API
  • วิธีกำหนดค่าฉาก AR พื้นฐาน
  • วิธีค้นหาพื้นผิวโดยใช้การทดสอบการตี AR
  • วิธีโหลดและแสดงผลโมเดล 3 มิติที่ซิงค์กับฟีดกล้องในชีวิตจริง
  • วิธีแสดงผลเงาตามโมเดล 3 มิติ

Codelab นี้มุ่งเน้นที่ AR API แนวคิดและโค้ดบล็อกที่ไม่เกี่ยวข้องจะได้รับการละเว้นและแสดงให้คุณเห็นในโค้ดที่เก็บข้อมูลที่เกี่ยวข้อง

สิ่งที่คุณต้องมี

คลิกลองเลยในอุปกรณ์ AR เพื่อลองทำขั้นตอนแรกของ Codelab นี้ หากได้รับหน้าเว็บที่มีข้อความแสดงว่า "เบราว์เซอร์ของคุณไม่มีฟีเจอร์ AR" ให้ตรวจสอบว่าอุปกรณ์ Android ของคุณติดตั้งบริการ Google Play สำหรับ AR แล้ว

2. ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์

ดาวน์โหลดโค้ด

  1. คลิกลิงก์ต่อไปนี้เพื่อดาวน์โหลดโค้ดทั้งหมดของ Codelab นี้ลงในเวิร์กสเตชัน

  1. แตกไฟล์ ZIP ที่ดาวน์โหลด ซึ่งจะแตกไฟล์โฟลเดอร์รูท (ar-with-webxr-master) ที่มีไดเรกทอรีของหลายขั้นตอนในโค้ดแล็บนี้ รวมถึงทรัพยากรทั้งหมดที่คุณต้องการ

โฟลเดอร์ step-03 และ step-04 มีสถานะสุดท้ายที่ต้องการของขั้นตอนที่ 3 และ 4 ของโค้ดแล็บนี้ รวมถึงผลลัพธ์ final ข้อมูลดังกล่าวมีไว้สำหรับใช้อ้างอิง

คุณทํางานเขียนโค้ดทั้งหมดในไดเรกทอรี work

ติดตั้งเว็บเซิร์ฟเวอร์

  1. คุณจะใช้เว็บเซิร์ฟเวอร์ของตนเองได้ หากยังไม่ได้ตั้งค่าไว้ ส่วนนี้จะอธิบายวิธีตั้งค่าเว็บเซิร์ฟเวอร์สำหรับ Chrome
    หากยังไม่ได้ติดตั้งแอปดังกล่าวในเวิร์กสเตชัน คุณสามารถติดตั้งได้จาก Chrome เว็บสโตร์

  1. หลังจากติดตั้งแอปเว็บเซิร์ฟเวอร์สำหรับ Chrome แล้ว ให้ไปที่ chrome://apps แล้วคลิกไอคอนเว็บเซิร์ฟเวอร์

ไอคอนเว็บเซิร์ฟเวอร์

คุณจะเห็นกล่องโต้ตอบนี้ซึ่งให้คุณกำหนดค่าเว็บเซิร์ฟเวอร์ในเครื่อง

กำหนดค่าเว็บเซิร์ฟเวอร์ Chrome

  1. คลิกเลือกโฟลเดอร์ แล้วเลือกโฟลเดอร์ ar-with-webxr-master ซึ่งจะช่วยให้คุณแสดงงานที่กำลังดำเนินการผ่าน URL ที่ไฮไลต์ในกล่องโต้ตอบของเว็บเซิร์ฟเวอร์ได้ (ในส่วน URL ของเว็บเซิร์ฟเวอร์)
  2. ในส่วนตัวเลือก (ต้องรีสตาร์ท) ให้เลือกช่องทำเครื่องหมายแสดง index.html โดยอัตโนมัติ
  3. สลับเว็บเซิร์ฟเวอร์เป็นหยุด แล้วกลับไปเป็นเริ่มแล้วรีสตาร์ทเว็บเซิร์ฟเวอร์ Chrome
  4. ตรวจสอบว่า URL ของเว็บเซิร์ฟเวอร์อย่างน้อย 1 รายการปรากฏขึ้น: http://127.0.0.1:8887 ซึ่งเป็น URL ของ localhost เริ่มต้น

ตั้งค่าการส่งต่อพอร์ต

กำหนดค่าอุปกรณ์ AR เพื่อให้อุปกรณ์เข้าถึงพอร์ตเดียวกันบนเวิร์กสเตชันเมื่อคุณไปที่ localhost:8887 บนอุปกรณ์ดังกล่าว

  1. ในเวิร์กสเตชันสำหรับนักพัฒนาซอฟต์แวร์ ให้ไปที่ chrome://inspect แล้วคลิกการส่งต่อพอร์ต... chrome://inspect
  2. ใช้กล่องโต้ตอบการตั้งค่าการส่งต่อพอร์ตเพื่อส่งต่อพอร์ต 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 บางรายการเพื่อแสดงปุ่มเริ่ม 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 ไฟล์นี้มีต้นแบบสำหรับการตั้งค่าประสบการณ์ 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

เมื่อคุณคลิกป้อนเทคโนโลยีความจริงเสริม (AR) โค้ดจะเรียกใช้ 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' เหมาะอย่างยิ่งสําหรับประสบการณ์ AR โดยมีพื้นที่อ้างอิงที่มีจุดเริ่มต้นใกล้กับผู้ชมและการติดตามที่เสถียร

เริ่มต้น this.localReferenceSpace ใน onSessionStarted() ด้วยโค้ดต่อไปนี้

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

กำหนดภาพเคลื่อนไหวแบบวนซ้ำ

  1. ใช้ requestAnimationFrame ของ XRSession เพื่อเริ่มลูปการแสดงผล ซึ่งคล้ายกับ 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 นี้จะอธิบายตำแหน่งและการวางแนวของอุปกรณ์ในพื้นที่ว่าง นอกจากนี้ยังมีอาร์เรย์ของ XRView ซึ่งอธิบายมุมมองทั้งหมดที่ควรแสดงผลฉากเพื่อให้แสดงบนอุปกรณ์ปัจจุบันได้อย่างถูกต้อง ขณะที่ VR ภาพสเตอริโอมี 2 มุมมอง (1 มุมมองสำหรับแต่ละตา) อุปกรณ์ AR จะมีเพียงมุมมองเดียว
    ข้อมูลใน pose.views มักใช้เพื่อกำหนดค่าเมทริกซ์มุมมองและเมทริกซ์การฉายของกล้องเสมือน การตั้งค่านี้จะส่งผลต่อการจัดวางฉากในแบบ 3 มิติ เมื่อกําหนดค่ากล้องแล้ว ระบบจะแสดงผลฉากได้
  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 พื้นฐานแล้ว ก็ถึงเวลาเริ่มโต้ตอบกับโลกแห่งความเป็นจริงโดยใช้ Hit Test ในส่วนนี้ คุณจะต้องเขียนโปรแกรมการทดสอบการตีและนำไปใช้ค้นหาพื้นผิวในชีวิตจริง

ทําความเข้าใจการทดสอบการทํางาน

โดยทั่วไปแล้ว Hit Test เป็นวิธีฉายเส้นตรงจากจุดหนึ่งๆ ในอวกาศไปยังทิศทางหนึ่งๆ และพิจารณาว่าเส้นนั้นตัดกับวัตถุที่น่าสนใจหรือไม่ ในตัวอย่างนี้ คุณเล็งอุปกรณ์ไปที่ตำแหน่งในโลกจริง ลองจินตนาการว่ารังสีเดินทางจากกล้องของอุปกรณ์และตรงไปยังโลกแห่งความเป็นจริงที่อยู่ตรงหน้า

WebXR Device API ช่วยให้คุณทราบว่ารังสีนี้ตัดกับวัตถุใดในโลกจริงหรือไม่ โดยพิจารณาจากความสามารถของ AR และความเข้าใจเกี่ยวกับโลกเบื้องหลัง

คําอธิบายการทดสอบ Hit

ขอXRSession พร้อมฟีเจอร์เพิ่มเติม

หากต้องการทำการทดสอบ Hit คุณต้องใช้ฟีเจอร์เพิ่มเติมเมื่อขอ XRSession

  1. ใน app.js ให้ค้นหา navigator.xr.requestSession
  2. เพิ่มฟีเจอร์ "hit-test" และ "dom-overlay" เป็น requiredFeature ดังนี้
this.xrSession = await navigator.xr.requestSession("immersive-ar", {
  requiredFeatures: ["hit-test", "dom-overlay"]
});
  1. กำหนดค่าการวางซ้อน DOM วางเลเยอร์องค์ประกอบ document.body เหนือมุมมองกล้อง AR ดังนี้
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);
}

หากต้องการทำการทดสอบ Hit คุณจะใช้ 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 นี้เพื่อทำการทดสอบ Hit ทุกเฟรม
    • หากไม่มีผลลัพธ์จากการทดสอบการตี แสดงว่า 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. เพิ่ม 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 หลังจากสร้างโปรแกรมแสดงผลแล้ว ให้ตั้งค่าต่อไปนี้ใน 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 จนจบแล้ว

ดูข้อมูลเพิ่มเติม