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

หากคุณเคยใช้ WebXR Device API อยู่แล้ว ก็ถือว่าเกือบเสร็จแล้ว

Joe Medley
Joe Medley

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

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

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

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

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

เทคโนโลยีความจริงเสริมจะเป็นส่วนเสริมที่มีคุณค่าสำหรับหน้าเว็บที่มีอยู่หรือหน้าเว็บใหม่จำนวนมาก เนื่องจากช่วยให้ใช้ 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
  }
}

การดำเนินการนี้จะเปิดใช้ปุ่ม "เข้าสู่ 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();
  }
}

พร็อพเพอร์ตี้เพื่ออำนวยความสะดวก

คุณอาจสังเกตเห็นว่าเราไฮไลต์ 2 บรรทัดในตัวอย่างโค้ดล่าสุด ออบเจ็กต์ 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);
  });
}

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

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() แสดงจะขึ้นอยู่กับประเภทพื้นที่อ้างอิงที่ขอ เราจะอธิบายเพิ่มเติมเมื่อถึงเฟรมวน ตอนนี้เราต้องเลือกประเภทข้อมูลอ้างอิงที่เหมาะกับเทคโนโลยีความจริงเสริม อีกครั้ง โดยใช้พร็อพเพอร์ตี้ my convenience

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 แบบสมจริง คุณจะเห็นในตอนแรกว่าฉากเป็นแบบคงที่และไม่ใช่ความจริงเสริม คุณลากและปัดนิ้วเพื่อไปยังส่วนต่างๆ ของฉากได้ หากคลิก "เริ่ม 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 ของกลุ่มทํางานเว็บที่สมจริง นอกจากนี้ เราเพิ่งเผยแพร่บทความการทดสอบ Hit ซึ่งอธิบาย API สําหรับตรวจหาพื้นผิวและวางสิ่งของเสมือนจริงในมุมมองกล้องในโลกจริง โปรดดูบทความเหล่านี้และติดตามบทความอื่นๆ อีกมากมายในบล็อก web.dev ในปีหน้า

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