Augmented Reality: คุณอาจรู้อยู่แล้ว

หากเคยใช้ WebXR Device API อยู่แล้ว ก็เกือบถึงเป้าหมายแล้ว

Joe Medley
Joe Medley

WebXR Device API จัดส่งในช่วงฤดูใบไม้ร่วงที่ผ่านมาใน Chrome 79 ดังที่ได้กล่าวไปแล้ว การใช้งาน API ของ Chrome ยังอยู่ระหว่างการพัฒนา Chrome ยินดีที่จะประกาศให้ ทราบว่างานบางส่วนเสร็จสมบูรณ์แล้ว Chrome 81 มีฟีเจอร์ใหม่ 2 รายการดังนี้

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

สำหรับข้อมูลเกี่ยวกับการทดสอบ Hit โปรดดูบทความร่วมการวางตำแหน่งวัตถุเสมือนจริงในมุมมองจริง โค้ดในบทความนี้อิงตามตัวอย่างเซสชัน AR ที่สมจริง (การสาธิต แหล่งที่มา) จากตัวอย่าง WebXR Device API ของ Immersive Web Working Group

ก่อนเจาะลึกโค้ด คุณควรใช้ตัวอย่างเซสชัน AR ที่สมจริงอย่างน้อย 1 ครั้ง คุณจะต้องมีโทรศัพท์ Android รุ่นใหม่ที่ใช้ Chrome 81 ขึ้นไป

มีประโยชน์อย่างไร

Augmented Reality จะเป็นส่วนเสริมที่มีประโยชน์สำหรับหน้าเว็บที่มีอยู่หรือหน้าเว็บใหม่จำนวนมาก โดยช่วยให้พวกเขาใช้งาน Use Case ของ AR ได้โดยไม่ต้องออกจากเบราว์เซอร์ เช่น ช่วยให้ผู้ใช้เรียนรู้ในเว็บไซต์ด้านการศึกษา และช่วยให้ผู้ที่มีโอกาสเป็นผู้ซื้อเห็นภาพสิ่งของในบ้านขณะช็อปปิ้ง

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

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

ขอเซสชัน

การขอเซสชันจะคล้ายกับที่คุณเคยเห็นมาก่อน ก่อนอื่นให้ดูว่าประเภทเซสชันที่คุณต้องการพร้อมใช้งานในอุปกรณ์ปัจจุบันหรือไม่โดยโทรไปที่ xr.isSessionSupported() แทนที่จะส่งคำขอ 'immersive-vr' เหมือนเดิม ให้ขอ 'immersive-ar'

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

ก่อนหน้านี้จะเป็นการเปิดใช้ปุ่ม "Enter AR" เมื่อผู้ใช้คลิก ให้โทรหา xr.requestSession() และส่งผ่าน 'immersive-ar' ด้วย

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

ร้านสะดวกซื้อ

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

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

จำว่า onSessionStarted() มีลักษณะอย่างไรในบทความก่อนหน้านี้ของฉัน:

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

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

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

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

ฉันต้องเพิ่มอะไรหลายอย่างเพื่อให้แสดงผล Augmented Reality ปิดพื้นหลังก่อน ผมจะตรวจสอบว่าต้องใช้พื้นหลังหรือไม่ นี่เป็นที่แรกที่ฉันจะใช้ร้านสะดวกซื้อ

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

  if (session.isImmersive) {
    removeBackground();
  }

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

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

  refSpaceType = xrSession.isImmersive ? 'local' : 'viewer';
  xrSession.requestReferenceSpace(refSpaceType).then((refSpace) => {
    xrSession.requestAnimationFrame(onXRFrame);
  });

}

พื้นที่อ้างอิง

บทความก่อนหน้าของฉันมีการดูพื้นที่อ้างอิง ตัวอย่างที่ฉันอธิบายนี้ ใช้ทั้ง 2 อย่างนี้เลย ถึงเวลาแก้ไขการละเลยแล้ว

พื้นที่อ้างอิงอธิบายความสัมพันธ์ระหว่างโลกเสมือนและสภาพแวดล้อมทางกายภาพของผู้ใช้ ซึ่งทำได้โดยการ:

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

สำหรับพื้นที่อ้างอิงทั้งหมด พิกัด X จะแสดงด้านซ้ายและขวา ตัว Y จะแสดงขึ้นและลง และ Z จะแสดงไปข้างหน้าและข้างหลัง ค่าบวก ได้แก่ ขวา ขึ้น และย้อนกลับ ตามลำดับ

พิกัดที่ XRFrame.getViewerPose() แสดงผลจะขึ้นอยู่กับประเภทพื้นที่อ้างอิงที่ขอ ข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้เมื่อเราอยู่ในลูปเฟรม ทีนี้เราต้องเลือกประเภท ข้อมูลอ้างอิงที่เหมาะกับ Augmented Reality วิธีนี้ใช้คุณสมบัติ ความสะดวกของฉัน

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

  if (session.isImmersive) {
    removeBackground();
  }

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

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

  refSpaceType = xrSession.isImmersive ? 'local' : 'viewer';
  xrSession.requestReferenceSpace(refSpaceType).then((refSpace) => {
    xrSession.requestAnimationFrame(onXRFrame);
  });
}

หากได้เข้าชมตัวอย่างเซสชัน AR ที่สมจริง คุณจะเห็นว่าในช่วงแรกฉากเป็นภาพนิ่งและไม่ได้ Augmented Reality เลย คุณใช้นิ้วลากและปัดเพื่อไปยังส่วนต่างๆ ของฉากได้ หากคลิก "เริ่มโหมด AR" พื้นหลังจะหายไปและคุณสามารถเคลื่อนไปรอบๆ ฉากได้โดยการเลื่อนอุปกรณ์ โหมดใช้พื้นที่อ้างอิงประเภทต่างๆ ข้อความที่ไฮไลต์ด้านบนจะแสดงวิธีที่เราเลือกฟีเจอร์นี้ โดยใช้ประเภทการอ้างอิงต่อไปนี้

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

viewer - ใช้บ่อยที่สุดสำหรับเนื้อหาที่แสดงในบรรทัดในหน้า โดยพื้นที่นี้จะอยู่หลังอุปกรณ์การดู เมื่อส่งผ่านไปยัง getViewerPose จะไม่มีการติดตาม และจะรายงานท่าทางที่ต้นทางเสมอ เว้นแต่แอปพลิเคชันจะแก้ไขด้วย XRReferenceSpace.getOffsetReferenceSpace() ตัวอย่างนี้ ใช้ฟีเจอร์นี้เพื่อเปิดใช้การเลื่อนแบบใช้การสัมผัสของกล้อง

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

โดยหลักแล้ว ไม่มีอะไรเปลี่ยนแปลงจากสิ่งที่ฉันทำในเซสชัน VR ที่อธิบายไว้ในบทความก่อนหน้านี้ ส่งประเภทพื้นที่อ้างอิงไปยัง XRFrame.getViewerPose() XRViewerPose ที่แสดงผลสำหรับประเภทพื้นที่อ้างอิงปัจจุบัน การใช้ viewer เป็นค่าเริ่มต้นจะช่วยให้หน้าเว็บแสดงตัวอย่างเนื้อหาได้ก่อนที่ระบบจะขอความยินยอมจากผู้ใช้สำหรับ AR หรือ VR ซึ่งแสดงให้เห็นจุดสำคัญ นั่นก็คือ เนื้อหาในหน้าใช้ลูปเฟรมเดียวกันกับเนื้อหาแบบสมจริง ซึ่งช่วยลดปริมาณโค้ดที่ต้องดูแล

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  let xrViewerPose = xrFrame.getViewerPose(refSpaceType);
  if (xrViewerPose) {
    // Render based on the pose.
  }
}

บทสรุป

บทความชุดนี้จะครอบคลุมเฉพาะข้อมูลพื้นฐานของการนำเนื้อหาที่สมจริงบนเว็บไปใช้เท่านั้น ตัวอย่าง WebXR Device API ของ Immersive Web Working Group แสดงความสามารถและกรณีการใช้งานอื่นๆ อีกมากมาย นอกจากนี้ เรายังเพิ่งเผยแพร่บทความการทดสอบ Hit ซึ่งอธิบาย API สำหรับการตรวจจับพื้นผิวและการวางวัตถุเสมือนจริงในมุมมองกล้องของจริง ลองอ่านและชมบล็อก web.dev สำหรับบทความอื่นๆ ในปีหน้า

รูปภาพโดย David Grandmougin ใน Unsplash