ยินดีต้อนรับสู่เว็บสมจริง

เว็บที่สมจริงหมายถึงประสบการณ์โลกเสมือนจริงที่โฮสต์ผ่านเบราว์เซอร์ ประสบการณ์เสมือนจริงทั้งหมดนี้จะแสดงในเบราว์เซอร์หรือในชุดหูฟังที่เปิดใช้ VR

Joe Medley
Joe Medley

เว็บที่สมจริงหมายถึงประสบการณ์โลกเสมือนจริงที่โฮสต์ผ่านเบราว์เซอร์ ซึ่งครอบคลุมประสบการณ์ Virtual Reality (VR) ทั้งหมดที่แสดงในเบราว์เซอร์หรือในชุดหูฟังที่พร้อมใช้งาน VR เช่น Daydream ของ Google, Oculus Rift, Samsung Gear VR, HTC Vive และชุดหูฟัง Windows Mixed Reality รวมถึงประสบการณ์ Augmented Reality ที่พัฒนาขึ้นสำหรับอุปกรณ์เคลื่อนที่ที่พร้อมใช้งาน AR

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

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

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

ผมจะไปที่นั่นได้ยังไง

เว็บที่สมจริงมีให้บริการในรูปแบบเริ่มต้นมาเกือบ 1 ปีแล้ว ซึ่งทำได้ผ่าน WebVR 1.1 API ที่พร้อมใช้งานในช่วงทดลองใช้จากต้นทางมาตั้งแต่ Chrome 62 Firefox และ Edge รวมถึง polyfill สําหรับ Safari ยังรองรับ API ดังกล่าวด้วย

แต่ถึงเวลาแล้วที่เราจะเดินหน้าต่อไป

ช่วงทดลองใช้จากต้นทางสิ้นสุดลงเมื่อวันที่ 24 กรกฎาคม 2018 และมีการแทนที่ข้อกำหนดด้วย WebXR Device API และช่วงทดลองใช้จากต้นทางใหม่

What happened to WebVR 1.1?

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

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

WebXR Device API ได้รับการออกแบบและตั้งชื่อโดยคำนึงถึง Use Case ที่ขยายการให้บริการเหล่านี้ และเพื่อนำไปสู่เส้นทางที่ดีขึ้น ผู้ใช้งาน WebVR มุ่งมั่นที่จะเปลี่ยนไปใช้ WebXR Device API

WebXR Device API คืออะไร

WebXR Device API เป็นผลิตภัณฑ์ของกลุ่มชุมชนเว็บที่สมจริง (Immersive Web Community Group) ซึ่งมีผู้มีส่วนร่วมจาก Google, Microsoft, Mozilla และอื่นๆ เช่นเดียวกับข้อกำหนด WebVR ก่อนหน้า "X ใน XR" มีไว้เพื่อเป็นตัวแปรทางพีชคณิตที่หมายถึงอะไรก็ได้ในประสบการณ์ที่สมจริง ซึ่งพร้อมให้บริการในช่วงทดลองใช้เวอร์ชันต้นทางที่กล่าวถึงก่อนหน้านี้ รวมถึงผ่านโพลีฟิลล์

เมื่อเผยแพร่บทความนี้ครั้งแรกในช่วงเบต้าของ Chrome 67 เราได้เปิดใช้เฉพาะความสามารถของ VR เท่านั้น Augmented Reality พร้อมให้ใช้งานใน Chrome 69 แล้ว อ่านข้อมูลเกี่ยวกับเรื่องนี้ได้ในเทคโนโลยีความจริงเสริม (AR) สําหรับเว็บ

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

บทความนี้จะกล่าวถึงการเริ่ม หยุด และเรียกใช้เซสชัน XR รวมถึงข้อมูลเบื้องต้นเกี่ยวกับการประมวลผลอินพุต

สิ่งที่เราจะไม่พูดถึงคือวิธีวาดเนื้อหา AR/VR ไปยังหน้าจอ WebXR Device API ไม่มีฟีเจอร์การแสดงผลภาพ นั่นขึ้นอยู่กับคุณ การวาดภาพทำได้โดยใช้ WebGL API คุณทำได้หากมีความทะเยอทะยานมาก แต่เราขอแนะนำให้ใช้เฟรมเวิร์ก ตัวอย่างเว็บที่สมจริงใช้เว็บที่สร้างขึ้นเพื่อแสดงตัวอย่างโดยเฉพาะชื่อ Cottontail Three.js รองรับ WebXR ตั้งแต่เดือนพฤษภาคม แต่เราไม่เคยได้ยินเกี่ยวกับ A-Frame

การเริ่มต้นและเรียกใช้แอป

ขั้นตอนพื้นฐานมีดังนี้

  1. ขออุปกรณ์ XR
  2. หากมี ให้ขอเซสชัน XR หากต้องการให้ผู้ใช้ใส่โทรศัพท์ไว้ในชุดหูฟัง ลักษณะการทำงานนี้เรียกว่าเซสชันที่สมจริงและกำหนดให้ผู้ใช้ทำท่าทางสัมผัสเพื่อเข้าสู่เซสชัน
  3. ใช้เซสชันเพื่อเรียกใช้ลูปการแสดงผลซึ่งให้เฟรมรูปภาพ 60 เฟรมต่อวินาที วาดเนื้อหาที่เหมาะสมบนหน้าจอในแต่ละเฟรม
  4. เรียกใช้ลูปการแสดงผลจนกว่าผู้ใช้จะตัดสินใจออก
  5. จบเซสชัน XR

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

ขออุปกรณ์ XR

คุณจะเห็นโค้ดการตรวจหาองค์ประกอบมาตรฐานที่นี่ คุณสามารถรวมข้อมูลนี้ไว้ในฟังก์ชันที่ชื่อประมาณว่า checkForXR()

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

if (navigator.xr) {
    navigator.xr.requestDevice()
    .then(xrDevice => {
    // Advertise the AR/VR functionality to get a user gesture.
    })
    .catch(err => {
    if (err.name === 'NotFoundError') {
        // No XRDevices available.
        console.error('No XR devices available:', err);
    } else {
        // An error occurred while requesting an XRDevice.
        console.error('Requesting XR device failed:', err);
    }
    })
} else{
    console.log("This browser does not support the WebXR API.");
}

ขอเซสชัน XR

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

xrPresentationContext = htmlCanvasElement.getContext('xrpresent');
let sessionOptions = {
    // The immersive option is optional for non-immersive sessions; the value
    //   defaults to false.
    immersive: false,
    outputContext: xrPresentationContext
}
xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Use a WebGL context as a base layer.
    xrSession.baseLayer = new XRWebGLLayer(session, gl);
    // Start the render loop
})

เรียกใช้ลูปการแสดงผล

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

ขั้นตอนพื้นฐานของลูปการแสดงผลมีดังนี้

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

ส่งคำขอเฟรมงานนำเสนอ

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

เฟรมประเภทที่ 2 คือเฟรมการนำเสนอ ซึ่งแสดงโดยออบเจ็กต์ XRFrame ออบเจ็กต์นี้มีข้อมูลที่จำเป็นในการเรนเดอร์เฟรมเดียวของฉาก AR/VR ไปยังอุปกรณ์ การดำเนินการนี้อาจทำให้สับสนเล็กน้อยเนื่องจากระบบจะเรียกข้อมูลเฟรมการนำเสนอโดยเรียก requestAnimationFrame() ซึ่งทำให้เข้ากันได้กับ window.requestAnimationFrame()

ก่อนจะให้ข้อมูลอื่นๆ เพิ่มเติม เราขอเสนอรหัสบางส่วน ตัวอย่างด้านล่างแสดงวิธีเริ่มต้นและดูแลรักษาลูปการแสดงผล สังเกตการใช้เฟรมข้อความแบบ 2 ลักษณะ และสังเกตการเรียก requestAnimationFrame() แบบซ้ำ ระบบจะเรียกใช้ฟังก์ชันนี้ 60 ครั้งต่อวินาที

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
    // The time argument is for future use and not implemented at this time.
    // Process the frame.
    xrFrame.session.requestAnimationFrame(onFrame);
    }
});

ท่าทาง

ก่อนที่จะวาดอะไรบนหน้าจอ คุณต้องทราบว่าอุปกรณ์แสดงผลกำลังชี้ไปที่ใดและคุณต้องเข้าถึงหน้าจอได้ โดยทั่วไป ตำแหน่งและการวางแนวของสิ่งต่างๆ ใน AR/VR จะเรียกว่า "ท่าทาง" ทั้งอุปกรณ์รับชมและอุปกรณ์อินพุตมีท่าทาง (เราจะพูดถึงอุปกรณ์อินพุตในภายหลัง) ทั้งท่าทางของอุปกรณ์รับชมและอุปกรณ์อินพุตจะกำหนดเป็นเมทริกซ์ 4x4 ที่เก็บไว้ใน Float32Array ในลําดับคอลัมน์หลัก คุณรับท่าทางของผู้ชมได้โดยเรียกใช้ XRFrame.getDevicePose() บนออบเจ็กต์เฟรมภาพเคลื่อนไหวปัจจุบัน โปรดทดสอบเสมอเพื่อดูว่าคุณได้รับท่าทางที่ต้องการหรือไม่ ในกรณีที่เกิดข้อผิดพลาดและคุณไม่ต้องการวาดบนหน้าจอ

let pose = xrFrame.getDevicePose(xrFrameOfRef);
if (pose) {
    // Draw something to the screen.
}

ยอดดู

หลังจากตรวจสอบท่าทางแล้ว ก็ถึงเวลาวาดรูป ออบเจ็กต์ที่คุณวาดเรียกว่ามุมมอง (XRView) ซึ่งประเภทเซสชันจะมีความสําคัญในขั้นตอนนี้ ระบบจะดึงข้อมูลมุมมองจากออบเจ็กต์ XRFrame เป็นอาร์เรย์ หากคุณอยู่ในเซสชันที่ไม่ใช่แบบสมจริง อาร์เรย์จะมีมุมมองเดียว หากคุณอยู่ในเซสชันการดูแบบสมจริง อาร์เรย์จะมี 2 รายการสำหรับแต่ละตา

for (let view of xrFrame.views) {
    // Draw something to the screen.
}

นี่เป็นความแตกต่างที่สำคัญระหว่าง WebXR กับระบบอื่นๆ ที่ให้ประสบการณ์การดื่มด่ำ แม้ว่าการวนซ้ำผ่านมุมมองเดียวอาจดูเหมือนไม่มีจุดหมาย แต่การดำเนินการดังกล่าวจะช่วยให้คุณมีเส้นทางการแสดงผลเดียวสําหรับอุปกรณ์ที่หลากหลาย

ลูปการแสดงผลทั้งหมด

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

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
    // The time argument is for future use and not implemented at this time.
    let pose = xrFrame.getDevicePose(xrFrameOfRef);
    if (pose) {
        for (let view of xrFrame.views) {
        // Draw something to the screen.
        }
    }
    // Input device code will go here.
    frame.session.requestAnimationFrame(onFrame);
    }
}

จบเซสชัน XR

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

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Create a WebGL layer and initialize the render loop.
    xrSession.addEventListener('end', onSessionEnd);
});

// Restore the page to normal after immersive access has been released.
function onSessionEnd() {
    xrSession = null;

    // Ending the session stops executing callbacks passed to the XRSession's
    // requestAnimationFrame(). To continue rendering, use the window's
    // requestAnimationFrame() function.
    window.requestAnimationFrame(onDrawFrame);
}

การโต้ตอบทํางานอย่างไร

เราจะอธิบายวิธีโต้ตอบกับวัตถุใน AR หรือ VR เพียงคร่าวๆ เช่นเดียวกับอายุการใช้งานของแอปพลิเคชัน

WebXR Device API ใช้แนวทาง "ชี้แล้วคลิก" สำหรับอินพุตของผู้ใช้ เมื่อใช้แนวทางนี้ แหล่งข้อมูลอินพุตทุกแหล่งจะมีลำแสงเคอร์เซอร์ที่กําหนดไว้เพื่อระบุตําแหน่งที่อุปกรณ์อินพุตชี้อยู่ และเหตุการณ์เพื่อระบุเวลาที่เลือกรายการ แอปจะวาดเส้นของเคอร์เซอร์และแสดงจุดที่ชี้ เมื่อผู้ใช้คลิกอุปกรณ์อินพุต ระบบจะเรียกเหตุการณ์ select, selectStart และ selectEnd โดยเฉพาะ แอปจะระบุสิ่งที่มีการคลิกและตอบสนองอย่างเหมาะสม

อุปกรณ์อินพุตและลำแสงเคอร์เซอร์

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

let inputSources = xrSession.getInputSources();
for (let xrInputSource of inputSources) {
    let inputPose = frame.getInputPose(inputSource, xrFrameOfRef);
    if (!inputPose) {
    continue;
    }
    if (inputPose.gripMatrix) {
    // Render a virtual version of the input device
    //   at the correct position and orientation.
    }
    if (inputPose.pointerMatrix) {
    // Draw a ray from the gripMatrix to the pointerMatrix.
    }
}

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

การเลือกรายการในพื้นที่เสมือน

การชี้ไปที่สิ่งต่างๆ ใน AR/VR อย่างเดียวนั้นแทบจะไร้ประโยชน์ ผู้ใช้ต้องเลือกสิ่งต่างๆ ได้จึงจะทําสิ่งใดๆ ที่เป็นประโยชน์ได้ WebXR Device API มีเหตุการณ์ 3 รายการสําหรับการตอบสนองต่อการโต้ตอบของผู้ใช้ ได้แก่ select, selectStart และ selectEnd ซึ่งมีข้อบกพร่องที่เราคาดไม่ถึง กล่าวคือ เหตุการณ์จะบอกคุณเพียงว่ามีคลิกอุปกรณ์อินพุต ข้อมูลนี้ไม่ได้บอกคุณว่ามีการคลิกรายการใดในสภาพแวดล้อม ระบบจะเพิ่มตัวแฮนเดิลเหตุการณ์ลงในออบเจ็กต์ XRSession และควรเพิ่มทันทีที่พร้อมใช้งาน

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Create a WebGL layer and initialize the render loop.
    xrSession.addEventListener('selectstart', onSelectStart);
    xrSession.addEventListener('selectend', onSelectEnd);
    xrSession.addEventListener('select', onSelect);
});

โค้ดนี้อิงตามตัวอย่างการเลือกอินพุต ในกรณีที่คุณต้องการบริบทเพิ่มเติม

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

function onSelect(ev) {
    let inputPose = ev.frame.getInputPose(ev.inputSource, xrFrameOfRef);
    if (!inputPose) {
    return;
    }
    if (inputPose.pointerMatrix) {
    // Figure out what was clicked and respond.
    }
}

สรุป: มองไปข้างหน้า

ตามที่ได้กล่าวไปก่อนหน้านี้ เราคาดว่าเทคโนโลยีความจริงเสริมจะพร้อมใช้งานใน Chrome 69 (Canary ในช่วงเดือนมิถุนายน 2018) อย่างไรก็ตาม เราขอแนะนำให้คุณลองใช้ฟีเจอร์ที่เรามีให้จนถึงตอนนี้ เราต้องการความคิดเห็นของคุณเพื่อปรับปรุงฟีเจอร์นี้ให้ดียิ่งขึ้น ติดตามความคืบหน้าได้โดยดูที่ WebXR Hit Testing ใน ChromeStatus.com นอกจากนี้ คุณยังติดตามจุดยึด WebXR ได้ด้วย ซึ่งจะช่วยปรับปรุงการติดตามท่าทาง