Virtual Reality ขึ้นสู่เว็บแล้ว

ข้อมูลเบื้องต้นบางอย่างเพื่อเตรียมคุณให้พร้อมสำหรับประสบการณ์ที่สมจริงในหลายระดับ ได้แก่ Virtual Reality, Augmented Reality และอื่นๆ

Joe Medley
Joe Medley

ประสบการณ์ที่สมจริงมีให้ใช้งานในเว็บแล้วใน Chrome 79 WebXR Device API นำเทคโนโลยีความจริงเสมือน (VR) มาใช้งานจริง ส่วน Chrome 81 รองรับ Augmented Reality ในขณะที่การอัปเดต GamePad API จะขยายการใช้งาน การควบคุมขั้นสูงไปยัง VR เบราว์เซอร์อื่นๆ จะรองรับข้อกำหนดเหล่านี้ในเร็วๆ นี้ ได้แก่ Firefox Reality, เบราว์เซอร์ Oculus, เบราว์เซอร์ Helio ของ Magic Leap และ Magic Leap

บทความนี้จะเริ่มต้นซีรีส์บนเว็บสมจริง การผ่อนชำระนี้ครอบคลุมการตั้งค่าแอปพลิเคชัน WebXR พื้นฐาน ตลอดจนการเข้าและออกจากเซสชัน XR บทความต่อๆ ไปจะกล่าวถึงเฟรมลูป (ประสบการณ์การทำงานของ WebXR) ข้อมูลเฉพาะของ Augmented Reality และ WebXR Hit Test API ซึ่งหมายถึงการตรวจหาพื้นผิวในเซสชัน AR หากไม่ระบุไว้เป็นอย่างอื่น ทุกอย่างที่ฉันพูดถึงในบทความนี้และประสบความสำเร็จจะมีผลบังคับใช้ทั้งกับ AR และ VR เท่าๆ กัน

เว็บสมจริงคืออะไร

แม้ว่าเราจะใช้คำ 2 คำในการอธิบายประสบการณ์ที่สมจริง คือ Augmented Reality และ Virtual Reality แต่หลายคนก็คิดว่า 2 คำนี้ครอบคลุมตั้งแต่ความจริงเต็มรูปแบบไปจนถึงเสมือนจริงโดยสมบูรณ์ โดยมีระดับความสมจริงอยู่ระหว่างด้านต่างๆ เครื่องหมาย "X" ใน XR มีจุดประสงค์เพื่อสะท้อนว่าการคิดโดยใช้ตัวแปรพีชคณิตชนิดหนึ่งหมายถึงอะไรก็ตามในสเปกตรัมของประสบการณ์ที่สมจริง

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

ตัวอย่างของประสบการณ์ที่สมจริง ได้แก่

  • เกม
  • วิดีโอ 360 องศา
  • วิดีโอ 2 มิติแบบดั้งเดิม (หรือ 3 มิติ) ที่นำเสนอในสภาพแวดล้อมที่สมจริง
  • การซื้อบ้าน
  • การดูผลิตภัณฑ์ในบ้านก่อนตัดสินใจซื้อ
  • ศิลปะที่สมจริง
  • ของเจ๋งๆ ที่ใครๆ ก็นึกถึง

แนวคิดและการใช้งาน

เราจะอธิบายข้อมูลเบื้องต้นเกี่ยวกับการใช้ WebXR Device API หากต้องการดูข้อมูลเจาะลึกกว่าที่เราให้ไว้ โปรดดูตัวอย่าง WebXR ของ Immersive Web Working Group หรือเอกสารอ้างอิงที่เพิ่มขึ้นของ MDN หากคุณคุ้นเคยกับ WebXR Device API เวอร์ชันแรกๆ คุณควรดูข้อมูลเกี่ยวกับเนื้อหานี้ทั้งหมด มีการเปลี่ยนแปลง

โค้ดในบทความนี้อิงตามตัวอย่าง Barebones ของ Immersive Web Working Group (การสาธิต แหล่งที่มา) แต่ได้รับการแก้ไขเพื่อความชัดเจนและเรียบง่าย

ส่วนหนึ่งของการสร้างข้อกำหนด WebXR คือการปรับปรุงมาตรการด้านความปลอดภัยและความเป็นส่วนตัวเพื่อปกป้องผู้ใช้ การนำไปใช้จะต้องเป็นไปตามข้อกำหนดบางประการ หน้าเว็บหรือแอปต้องทำงานอยู่และโฟกัสอยู่ก่อนจึงจะขอข้อมูลที่ละเอียดอ่อนจากผู้ดูได้ หน้าเว็บหรือแอปต้องแสดง ผ่าน HTTPS ตัว API เองออกแบบมาเพื่อปกป้องข้อมูลที่ได้มาจากเซ็นเซอร์และกล้อง ซึ่งจำเป็นต้องใช้ในการทํางาน

ขอเซสชัน

การเข้าสู่เซสชัน XR ต้องใช้ท่าทางสัมผัสของผู้ใช้ โดยใช้การตรวจหาฟีเจอร์เพื่อทดสอบสำหรับ XRSystem (ผ่าน navigator.xr) และโทรหา XRSystem.isSessionSupported() โปรดทราบว่าใน Chrome เวอร์ชัน 79 และ 80 ออบเจ็กต์ XRSystem มีชื่อว่า XR

ในตัวอย่างด้านล่าง ฉันระบุว่าต้องการใช้เซสชัน Virtual Reality กับประเภทเซสชัน 'immersive-vr' เซสชันประเภทอื่นๆ คือ 'immersive-ar' และ 'inline' เซสชันในหน้ามีไว้สำหรับการนำเสนอเนื้อหา ภายใน HTML และใช้สำหรับเนื้อหาของทีเซอร์เป็นหลัก ตัวอย่างเซสชัน AR ที่สมจริงจะแสดงให้เห็นสิ่งนี้ ฉันจะอธิบายให้ฟังในบทความถัดไป

เมื่อทราบว่าระบบรองรับเซสชัน Virtual Reality แล้ว ผมก็เปิดใช้ปุ่มที่สามารถรับท่าทางสัมผัสของผู้ใช้ได้

if (navigator.xr) {
  const supported = await navigator.xr.isSessionSupported('immersive-vr');
  if (supported) {
    xrButton.addEventListener('click', onButtonClicked);
    xrButton.textContent = 'Enter VR';
    xrButton.enabled = supported; // supported is Boolean
  }
}

หลังจากเปิดใช้ปุ่ม ฉันจะรอเหตุการณ์การคลิกแล้วจึงขอเซสชัน

let xrSession = null;
function onButtonClicked() {
  if (!xrSession) {
    navigator.xr.requestSession('immersive-vr')
    .then((session) => {
      xrSession = session;
      xrButton.textContent = 'Exit XR';
      onSessionStarted(xrSession);
    });
  } else {
    xrSession.end();
  }
}

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

เข้าสู่เซสชัน

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

ฉันต้องมีองค์ประกอบ <canvas> เพื่อวาดฉากด้วย ไฟล์จะต้องเป็น WebGLRenderingContext หรือ WebGL2RenderingContext ที่ใช้ร่วมกับ XR ได้ การวาดภาพทั้งหมดจะดำเนินการโดยใช้ภาพหรือเฟรมเวิร์กแบบ WebGL เช่น Three.js

ตอนนี้มีที่สำหรับวาดภาพแล้ว ฉันต้องหาแหล่งเนื้อหาเพื่อวาดรูป สำหรับเรื่องดังกล่าว ผมจะสร้างอินสแตนซ์ของ XRWebGLLayer ผมเชื่อมโยงโฆษณากับ ผืนผ้าใบด้วยการเรียก XRSession.updateRenderState()

เมื่อผมอยู่ในเซสชันแล้ว ผมอยากรู้ว่า สิ่งต่างๆ อยู่ที่ไหนใน Virtual Reality ฉันต้องการพื้นที่อ้างอิง พื้นที่อ้างอิง 'local-floor' คือพื้นที่หนึ่งที่ต้นทางอยู่ใกล้กับมุมมอง และแกน Y เป็น 0 ที่ระดับชั้นและไม่ควรเคลื่อนที่ ยังมีพื้นที่อ้างอิงประเภทอื่นๆ ด้วย แต่เป็นหัวข้อที่ซับซ้อนมากกว่าที่เราจะพูดถึงในส่วนนี้ ผมบันทึกพื้นที่อ้างอิงลงในตัวแปรเพราะจะต้องใช้เมื่อวาดบนหน้าจอ

function onSessionStarted(xrSession) {
  xrSession.addEventListener('end', onSessionEnded);

  let canvas = document.createElement('canvas');
  webGLRenContext = canvas.getContext('webgl', { xrCompatible: true });

  xrSession.updateRenderState({
    baseLayer: new XRWebGLLayer(xrSession, webGLRenContext)
  });

  xrSession.requestReferenceSpace('local-floor')
  .then((refSpace) => {
    xrRefSpace = refSpace;
    xrSession.requestAnimationFrame(onXRFrame);
  });
}

หลังจากได้รับพื้นที่อ้างอิงแล้ว ฉันจะโทรหา XRSession.requestAnimationFrame() นี่คือจุดเริ่มต้นของการนำเสนอเนื้อหาเสมือนจริง ซึ่งดำเนินการในลูปเฟรม

เรียกใช้ลูปเฟรม

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

ขั้นตอนพื้นฐานสำหรับการวนซ้ำของเฟรมมีดังนี้

  1. โทรมาที่ XRSession.requestAnimationFrame() ในการตอบกลับ User Agent จะเรียกใช้ XRFrameRequestCallback ตามที่คุณกำหนด
  2. ในฟังก์ชันเรียกกลับ ให้ทำดังนี้
    1. โทรหา XRSession.requestAnimationFrame() อีกครั้ง
    2. โพสต์ท่าทางของผู้ชม
    3. ผ่าน ("bind") WebGLFramebuffer จาก XRWebGLLayer ไปยัง WebGLRenderingContext
    4. วนซ้ำออบเจ็กต์ XRView แต่ละรายการ โดยดึงข้อมูล XRViewport จาก XRWebGLLayer และส่งไปยัง WebGLRenderingContext
    5. วาดสิ่งที่อยู่ในเฟรมบัฟเฟอร์

ส่วนที่เหลือของบทความนี้จะอธิบายขั้นตอนที่ 1 และขั้นตอนที่ 2 ซึ่งก็คือการตั้งค่าและการเรียกใช้ XRFrameRequestCallback รายการที่เหลือของขั้นตอนที่ 2 จะครอบคลุมในส่วนที่ 2

XRFrameRequestCallback

XRFrameRequestCallback คุณเป็นผู้กำหนด โดยใช้พารามิเตอร์ 2 ตัว ได้แก่ DOMHighResTimeStamp และอินสแตนซ์ XRFrame ออบเจ็กต์ XRFrame ให้ข้อมูลที่จำเป็นต่อการแสดงผลเฟรมเดียวไปยังจอแสดงผล อาร์กิวเมนต์ DOMHighResTimeStamp มีไว้สำหรับการใช้งานในอนาคต

ก่อนที่จะทำอย่างอื่น ฉันจะขอเฟรมภาพเคลื่อนไหวถัดไป ตามที่ได้กล่าวไว้ก่อนหน้านี้ ระยะเวลาของเฟรมจะกำหนดโดย User Agent โดยอิงจากฮาร์ดแวร์พื้นฐาน การขอเฟรมถัดไปก่อนทำให้มั่นใจว่าลูปเฟรมจะดำเนินต่อไปหากมีบางอย่างระหว่างการติดต่อกลับมีข้อผิดพลาด

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  // Render a frame.
}

ถึงตอนนี้ก็ถึงเวลาที่จะวาดบางสิ่งให้ผู้ชมฟังแล้ว เรามาพูดถึง ตอนที่ 2 กันต่อนะ ก่อนที่จะไปที่นั่น เราขอแสดงวิธีจบเซสชันกัน

จบเซสชัน

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

จำได้จากการเข้าสู่เซสชันว่าระหว่างการตั้งค่าฉันได้เพิ่มเครื่องจัดการเหตุการณ์ onend แล้ว

function onSessionStarted(xrSession) {
  xrSession.addEventListener('end', onSessionEnded);
  // More setup…
}

ภายในตัวแฮนเดิลเหตุการณ์ ให้คืนค่าสถานะของแอปก่อนที่ผู้ใช้จะเข้าสู่เซสชัน

function onSessionEnded(event) {
  xrSession = null;
  xrButton.textContent = 'Enter VR';
}

บทสรุป

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

รูปภาพโดย JESHOOTS.COM ใน Unsplash