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

พื้นฐานบางอย่างที่จะช่วยให้คุณพร้อมสำหรับประสบการณ์การใช้งานที่สมจริงหลากหลายรูปแบบ ได้แก่ เทคโนโลยีความจริงเสมือน (VR), เทคโนโลยีความจริงเสริม (AR) และทุกอย่างที่อยู่ระหว่างนั้น

Joe Medley
Joe Medley

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

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

Immersive Web คืออะไร

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

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

ตัวอย่างประสบการณ์การใช้งานแบบสมจริง ได้แก่

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

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

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

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

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

ขอเซสชัน

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

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

เมื่อทราบว่าระบบรองรับเซสชันเทคโนโลยีความจริงเสมือน (VR) แล้ว ฉันจะเปิดใช้ปุ่มที่ช่วยให้ฉันรับท่าทางของผู้ใช้ได้

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> เพื่อวาดฉากด้วย ต้องเป็น XR-compatible WebGLRenderingContext หรือ WebGL2RenderingContext การวาดทั้งหมดจะทำโดยใช้เฟรมเวิร์กที่อิงตาม WebGL เช่น Three.js

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

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

เรียกใช้การวนซ้ำเฟรม

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

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

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