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

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

Joe Medley
Joe Medley

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

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

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

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

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

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

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

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

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

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

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

ขอเซสชัน

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

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

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

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()

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

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

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

ขั้นตอนพื้นฐานของเฟรมลูปมีดังนี้

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

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