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

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

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

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

AR คืออะไร

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

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

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

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

  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 ของ 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. ในส่วนตัวเลือก (ต้องรีสตาร์ท) ให้เลือกช่องทำเครื่องหมายแสดง index.html โดยอัตโนมัติ
  3. สลับเว็บเซิร์ฟเวอร์เป็นหยุด แล้วกลับไปเป็นเริ่มรีสตาร์ท Chrome Web Server
  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 ในเบราว์เซอร์

คุณควรเห็นหน้าเว็บที่มีปุ่มเริ่ม Augmented Reality

อย่างไรก็ตาม หากเห็นหน้าข้อผิดพลาดเบราว์เซอร์ไม่รองรับ แสดงว่าอุปกรณ์ของคุณอาจไม่รองรับ

รองรับ ARCore

ไม่รองรับ ARCore

ตอนนี้การเชื่อมต่อกับเว็บเซิร์ฟเวอร์ควรใช้งานได้กับอุปกรณ์ AR

  1. คลิกเริ่มเทคโนโลยีความจริงเสริม ระบบอาจแจ้งให้คุณติดตั้ง ARCore

ข้อความแจ้งให้ติดตั้ง ARCore

คุณจะเห็นข้อความแจ้งสิทธิ์เข้าถึงกล้องในครั้งแรกที่เรียกใช้แอป AR

Chrome ขอสิทธิ์เข้าถึงกล้องกล่องโต้ตอบสิทธิ์

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

3. กำหนดค่า WebXR

ในขั้นตอนนี้ คุณจะได้เรียนรู้วิธีตั้งค่าเซสชัน WebXR และฉาก AR พื้นฐาน หน้า HTML มีการจัดรูปแบบ CSS และ JavaScript เพื่อเปิดใช้ฟังก์ชัน AR พื้นฐาน ซึ่งจะช่วยเร่งกระบวนการตั้งค่า ทำให้ Codelab มุ่งเน้นไปที่ฟีเจอร์ AR ได้

หน้า HTML

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

เมื่อคลิกเข้าสู่เทคโนโลยีความจริงเสริม โค้ดจะเรียกใช้ 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 นี้อธิบายตำแหน่งและการวางแนวของอุปกรณ์ในพื้นที่ นอกจากนี้ ยังมีอาร์เรย์ของ XRViews ซึ่งอธิบายมุมมองทั้งหมดที่ควรแสดงฉากเพื่อให้แสดงอย่างถูกต้องในอุปกรณ์ปัจจุบัน แม้ว่า 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

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

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

คำอธิบายการทดสอบตัวชี้

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

หากต้องการทำการทดสอบความนิยม คุณจะต้องมีฟีเจอร์เพิ่มเติมเมื่อขอ 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);
}

หากต้องการทำการทดสอบการตรวจจับการแตะ คุณต้องใช้ 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. เพิ่ม 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 แล้ว

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