Thực tế tăng cường: Có thể bạn đã biết đến tính năng này

Nếu đã sử dụng API Thiết bị WebXR, thì bạn đã gần như hoàn tất.

Joe Medley
Joe Medley

WebXR Device API được ra mắt vào mùa thu năm ngoái trên Chrome 79. Như đã nêu, việc triển khai API của Chrome đang trong quá trình hoàn thiện. Chrome rất vui mừng được thông báo rằng một số công việc đã hoàn tất. Chrome 81 có hai tính năng mới:

Bài viết này đề cập đến công nghệ thực tế tăng cường. Nếu đã sử dụng API Thiết bị WebXR, bạn sẽ rất vui khi biết rằng có rất ít kiến thức mới cần tìm hiểu. Việc tham gia phiên WebXR cũng tương tự như vậy. Việc chạy vòng lặp khung về cơ bản cũng tương tự như vậy. Điểm khác biệt nằm ở các cấu hình cho phép hiển thị nội dung phù hợp với thực tế tăng cường. Nếu chưa nắm rõ các khái niệm cơ bản về WebXR, bạn nên đọc các bài đăng trước của tôi về API Thiết bị WebXR hoặc ít nhất là nắm rõ các chủ đề được đề cập trong đó. Bạn phải biết cách yêu cầu và tham gia một phiên, đồng thời phải biết cách chạy vòng lặp khung.

Để biết thông tin về việc kiểm thử lượt truy cập, hãy xem bài viết đi kèm Định vị đối tượng ảo trong khung hiển thị thực tế. Mã trong bài viết này dựa trên mẫu Phiên AR sống động (nguồn minh hoạ) từ các mẫu API Thiết bị WebXR của Nhóm làm việc về Web sống động.

Trước khi đi sâu vào mã, bạn nên sử dụng mẫu Phiên thực tế tăng cường sống động ít nhất một lần. Bạn cần có một chiếc điện thoại Android hiện đại, chạy Chrome 81 trở lên.

Công cụ này hữu ích khi nào?

Thực tế tăng cường sẽ là một bổ sung có giá trị cho nhiều trang web hiện có hoặc mới bằng cách cho phép các trang web đó triển khai các trường hợp sử dụng AR mà không cần rời khỏi trình duyệt. Ví dụ: công nghệ này có thể giúp mọi người tìm hiểu trên các trang web giáo dục và cho phép người mua tiềm năng hình dung các đối tượng trong nhà trong khi mua sắm.

Hãy xem xét trường hợp sử dụng thứ hai. Hãy tưởng tượng việc mô phỏng việc đặt một bản trình bày kích thước thực của một đối tượng ảo trong một cảnh thực. Sau khi đặt, hình ảnh sẽ vẫn ở trên bề mặt đã chọn, xuất hiện theo kích thước mong muốn nếu mục thực tế nằm trên bề mặt đó và cho phép người dùng di chuyển xung quanh cũng như gần hoặc xa hơn. Điều này giúp người xem hiểu rõ hơn về đối tượng so với hình ảnh hai chiều.

Tôi có hơi đi trước một chút. Để thực sự làm được những gì tôi đã mô tả, bạn cần có chức năng AR và một số phương tiện phát hiện bề mặt. Bài viết này đề cập đến cách thứ nhất. Bài viết đi kèm về API kiểm thử lượt nhấn WebXR (được liên kết ở trên) sẽ đề cập đến API sau.

Yêu cầu một phiên

Việc yêu cầu một phiên rất giống với những gì bạn đã thấy trước đây. Trước tiên, hãy tìm hiểu xem loại phiên bạn muốn có hoạt động trên thiết bị hiện tại hay không bằng cách gọi xr.isSessionSupported(). Thay vì yêu cầu 'immersive-vr' như trước, hãy yêu cầu '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
  }
}

Như trước đây, thao tác này sẽ bật nút "Enter AR" (Nhập thực tế tăng cường). Khi người dùng nhấp vào nút này, hãy gọi xr.requestSession(), đồng thời truyền '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();
  }
}

Thuộc tính tiện lợi

Có thể bạn đã nhận thấy tôi đã làm nổi bật hai dòng trong đoạn mã mẫu cuối cùng. Đối tượng XRSession có vẻ như có một thuộc tính có tên là isImmersive. Đây là một thuộc tính tiện lợi mà tôi tự tạo và không thuộc quy cách. Tôi sẽ sử dụng thuộc tính này sau để đưa ra quyết định về nội dung hiển thị cho người xem. Tại sao thuộc tính này không phải là một phần của API? Vì ứng dụng của bạn có thể cần theo dõi thuộc tính này theo cách khác, vì vậy các tác giả thông số kỹ thuật đã quyết định đảm bảo API này không bị nhiễm độc.

Vào một phiên

Hãy nhớ lại giao diện của onSessionStarted() trong bài viết trước của tôi:

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);
  });
}

Tôi cần thêm một vài thứ để tính đến việc kết xuất thực tế tăng cường. Tắt nền Trước tiên, tôi sẽ xác định xem mình có cần nền hay không. Đây là nơi đầu tiên tôi sẽ sử dụng thuộc tính tiện lợi.

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);
  });

}

Không gian tham chiếu

Các bài viết trước của tôi đã lướt qua không gian tham chiếu. Mẫu mà tôi đang mô tả sử dụng hai trong số đó, vì vậy, đã đến lúc khắc phục thiếu sót đó.

Không gian tham chiếu mô tả mối quan hệ giữa thế giới ảo và môi trường thực của người dùng. Cách thức hoạt động của tính năng này như sau:

  • Chỉ định gốc cho hệ toạ độ dùng để biểu thị các vị trí trong thế giới ảo.
  • Chỉ định xem người dùng có dự kiến di chuyển trong hệ toạ độ đó hay không.
  • Liệu hệ toạ độ đó có ranh giới được thiết lập trước hay không. (Các ví dụ hiển thị ở đây không sử dụng hệ toạ độ có ranh giới được thiết lập trước.)

Đối với tất cả không gian tham chiếu, toạ độ X biểu thị bên trái và bên phải, Y biểu thị lên và xuống, còn Z biểu thị về phía trước và phía sau. Các giá trị dương tương ứng là sang phải, lên trên và lùi.

Toạ độ do XRFrame.getViewerPose() trả về phụ thuộc vào loại không gian tham chiếu được yêu cầu. Chúng ta sẽ tìm hiểu thêm về điều đó khi đến vòng lặp khung hình. Hiện tại, chúng ta cần chọn một loại tệp tham chiếu phù hợp với công nghệ thực tế tăng cường. Xin nhắc lại, phần này sử dụng thuộc tính tiện lợi của tôi.

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);
  });
}

Nếu đã truy cập vào Mẫu phiên AR sống động, bạn sẽ nhận thấy ban đầu cảnh này ở trạng thái tĩnh và hoàn toàn không phải là thực tế tăng cường. Bạn có thể kéo và vuốt bằng ngón tay để di chuyển xung quanh cảnh. Nếu nhấp vào "START AR" (BẮT ĐẦU AR), nền sẽ biến mất và bạn có thể di chuyển xung quanh cảnh bằng cách di chuyển thiết bị. Các chế độ này sử dụng các loại không gian tham chiếu khác nhau. Văn bản được làm nổi bật ở trên cho biết cách chọn thuộc tính này. Phương thức này sử dụng các loại tham chiếu sau:

local – Điểm gốc nằm ở vị trí của người xem tại thời điểm tạo phiên. Tức là trải nghiệm không nhất thiết phải có giá sàn được xác định rõ và vị trí chính xác của điểm gốc có thể thay đổi tuỳ theo nền tảng. Mặc dù không có ranh giới được thiết lập trước cho không gian, nhưng người dùng có thể xem nội dung mà không cần di chuyển ngoài việc xoay. Như bạn có thể thấy trong ví dụ về AR của chúng tôi, một số chuyển động trong không gian có thể xảy ra.

viewer – Được sử dụng thường xuyên nhất cho nội dung trình bày cùng dòng trong trang và không gian này nằm sau thiết bị xem. Khi được truyền đến getViewerPose, phương thức này sẽ không cung cấp tính năng theo dõi và do đó luôn báo cáo một tư thế tại gốc trừ phi ứng dụng sửa đổi tư thế đó bằng XRReferenceSpace.getOffsetReferenceSpace(). Mẫu này sử dụng tính năng này để bật tính năng kéo máy ảnh dựa trên thao tác chạm.

Chạy vòng lặp khung hình

Về mặt khái niệm, không có gì thay đổi so với những gì tôi đã làm trong phiên VR được mô tả trong các bài viết trước của tôi. Truyền loại không gian tham chiếu đến XRFrame.getViewerPose(). XRViewerPose được trả về sẽ dành cho loại không gian tham chiếu hiện tại. Việc sử dụng viewer làm chế độ mặc định cho phép một trang hiển thị bản xem trước nội dung trước khi yêu cầu sự đồng ý của người dùng cho Thực tế tăng cường (AR) hoặc Thực tế ảo (VR). Hình ảnh này minh hoạ một điểm quan trọng: nội dung cùng dòng sử dụng cùng một vòng lặp khung như nội dung sống động, giúp cắt giảm lượng mã cần duy trì.

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

Kết luận

Chuỗi bài viết này chỉ đề cập đến những kiến thức cơ bản về cách triển khai nội dung sống động trên web. Các mẫu API WebXR Device API của Nhóm làm việc với web nhập vai trình bày nhiều chức năng và trường hợp sử dụng khác. Chúng tôi cũng vừa phát hành một bài viết về kiểm thử lượt nhấn, trong đó giải thích về một API để phát hiện các bề mặt và đặt các mục ảo trong chế độ xem máy ảnh thực tế. Hãy khám phá và xem blog web.dev để biết thêm các bài viết trong năm tới.

Ảnh chụp của David Grandmougin trên Unsplash