สร้างแอป 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 มีการใช้กันอย่างแพร่หลายในแอปหลังจากเปิดตัว ARCore ของ Google และ ARKit ของ Apple ไม่ว่าจะเป็นฟิลเตอร์เซลฟีหรือเกมที่ใช้ AR

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

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

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

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

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

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

สิ่งที่ต้องมี

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

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

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

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

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

โฟลเดอร์ step-03 และ step-04 มีสถานะสิ้นสุดที่ต้องการของขั้นตอนที่ 3 และ 4 ของ Codelab นี้ รวมถึงผลลัพธ์ 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 ในเบราว์เซอร์

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

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

รองรับ ARCore

ไม่รองรับ ARCore

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

  1. คลิกเริ่ม Augmented Reality คุณอาจได้รับแจ้งให้ติดตั้ง 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

โปรดตรวจสอบการมีอยู่ของ navigator.xr และฟีเจอร์ XR ที่จำเป็นก่อนที่ผู้ใช้จะทำงานกับ AR ได้ ออบเจ็กต์ navigator.xr คือจุดแรกเข้าสำหรับ WebXR Device API ดังนั้นจึงควรมีอยู่หากอุปกรณ์ใช้งานร่วมกันได้ นอกจากนี้ ให้ตรวจสอบว่าระบบรองรับโหมดเซสชัน "immersive-ar"

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

ทำความเข้าใจการทดสอบ Hit

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

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

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

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

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

  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 ที่ระบุซึ่งโหลดโมเดล 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() ซึ่งคำนวณการทดสอบ Hit ได้

  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 ทุกเฟรม:
    • หากไม่มีผลการทดสอบ 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);
  }
}

ทดสอบแอป

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

  1. เมื่อเรียกใช้แอป คุณควรเห็นเส้นยึดที่เคลื่อนไปตามพื้นผิวของพื้น หากไม่ ให้ลองมองไปรอบๆ ช้าๆ ด้วยโทรศัพท์
  2. เมื่อเห็นเส้นด้ายดังกล่าว ให้แตะเส้นตรงนั้น ควรวางดอกทานตะวันไว้ที่ด้านบน คุณอาจต้องขยับไปรอบๆ เล็กน้อยเพื่อให้แพลตฟอร์ม AR พื้นฐานตรวจจับพื้นผิวในโลกจริงได้ดียิ่งขึ้น แสงน้อยและพื้นผิวที่ไม่มีลักษณะต่างๆ จะลดคุณภาพของความเข้าใจของฉากและเพิ่มโอกาสที่จะไม่พบ Hit หากพบปัญหา ให้ตรวจสอบโค้ด step-04/app.js เพื่อดูตัวอย่างที่ใช้งานได้ของขั้นตอนนี้

5. เพิ่มเงา

การสร้างฉากที่สมจริงจะต้องมีองค์ประกอบต่างๆ เช่น แสงและเงาที่เหมาะสมบนวัตถุดิจิทัลที่ช่วยเพิ่มความสมจริงและการสมจริงในฉาก

three.js จะจัดการแสงและเงา คุณระบุได้ว่าแสงใดควรทำให้เกิดเงา วัสดุใดที่ควรรับและแสดงผลเงาเหล่านี้ และวัตถุใดสามารถสร้างเงาได้ ฉากของแอปนี้มีแสงที่ก่อให้เกิดเงาและพื้นผิวราบเรียบเพื่อแสดงเฉพาะเงา

  1. เปิดใช้เงาใน WebGLRenderer ของ three.js หลังจากสร้างตัวแสดงผล ให้ตั้งค่าต่อไปนี้ใน 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. แหล่งข้อมูลเพิ่มเติม

ยินดีด้วย คุณใช้ WebXR จนจบ Codelab นี้ใน AR แล้ว

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