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, bạn gần như đã hoàn thành rồi.

Joe Medley
Joe Medley

WebXR Device API đã được vận chuyển vào Chrome 79 vào mùa thu năm ngoái. Như đã đề cập, việc triển khai API của Chrome đang trong quá trình hoàn thiện. Chrome rất vui mừng 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 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. Bước vào một phiên WebXR gần như tương tự. Việc chạy vòng lặp khung cũng gần như tương tự như vậy. Sự khác biệt nằm ở cấu hình cho phép nội dung hiển thị phù hợp với chế độ thực tế tăng cường. Nếu chưa hiểu rõ các khái niệm cơ bản về WebXR, thì bạn nên đọc các bài đăng trước đây của tôi về WebXR Device API hoặc ít nhất là quen thuộc với các chủ đề được đề cập trong đó. Bạn nên biết cách yêu cầu và tham gia phiên và 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 Immersive AR (bản minh hoạ nguồn) từ mẫu WebXR Device API của Nhóm làm việc trực quan web.

Trước khi tìm hiểu kỹ hơn về 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ó điện thoại Android hiện đại chạy Chrome 81 trở lên.

Mục đích của việc này là gì?

Thực tế tăng cường sẽ là một yếu tố bổ sung có giá trị cho nhiều trang web mới hoặc hiện có bằng cách cho phép các trang web này 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ụ: Google Analytics 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 trực quan hoá các đồ vật trong nhà của họ khi mua sắm.

Hãy xem xét trường hợp sử dụng thứ hai. Hãy tưởng tượng mô phỏng việc đặt một bản mô tả một đối tượng ảo ở kích thước thật 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 kích thước sẽ hiển thị nếu mục thực tế ở trên bề mặt đó, đồng thời cho phép người dùng di chuyển xung quanh cũng như gần hoặc xa hơn đối tượng đó. Cách 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 đang đi trước một chút. Để thực sự làm như 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 các khu vực. Bài viết này đề cập đến phần trước. Bài viết đi kèm về API Kiểm tra lượt truy cập WebXR (được liên kết ở trên) đề cập đến phần sau.

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

Yêu cầu phiên rất giống với những gì bạn đã từng 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, nút này sẽ bật nút "Enter AR". 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();
  }
}

Cơ sở lưu trú tiện lợi

Bạn có thể nhận thấy rằng tôi đã đánh dấu 2 dòng trong mã mẫu gần đây nhất. Đối tượng XRSession sẽ có vẻ như có một thuộc tính tên là isImmersive. Đây là thuộc tính tiện lợi mà tôi tự tạo và không thuộc thuộc tính này. Tôi sẽ sử dụng thuộc tính này sau để quyết định xem thuộc tính nào sẽ 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, tác giả thông số kỹ thuật đã quyết định giữ cho API sạch.

Tham gia 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 bổ sung một số thứ liên quan đế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 của mình.

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 chỉ lướt qua không gian tham khảo. Mẫu mà tôi 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 tế của người dùng. Trang thông tin thực hiện việc này bằng cách:

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

Đối với tất cả cá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ị theo chiều lên và xuống, còn Z biểu thị tiến và lùi. Các giá trị dương lần lượt là đúng, lê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ề vòng lặp khung. Hiện tại, chúng ta cần chọn một loại tham chiếu phù hợp với thực tế tăng cường. Xin nhắc lại, tính năng 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 Mẫu phiên thực tế tăng cường sống động (Immersive AR), ban đầu, cảnh sẽ ở dạng tĩnh và hoàn toàn không 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 bạn nhấp vào "BẮT ĐẦU AR", thì 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ế độ sử dụng nhiều loại không gian tham chiếu. Văn bản được đánh dấu ở trên cho thấy cách nó được chọn. Phương thức này sử dụng các kiểu tham chiếu sau:

local – Điểm gốc ở vị trí của người xem tại thời điểm tạo phiên. Điều này có nghĩa là trải nghiệm không nhất thiết phải có giá sàn được xác định rõ ràng và vị trí chính xác 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 sẵn cho không gian, nhưng dự kiến rằng nội dung có thể được xem mà không có chuyển động nào khác ngoài chế độ xoay. Như bạn có thể thấy từ ví dụ về AR của chúng tôi, có thể có một số chuyển động trong không gian.

viewer – Được dùng thường xuyên nhất cho nội dung được trình bày cùng dòng trong trang, không gian này theo sau thiết bị xem. Khi được truyền đến getViewerPose, hệ thống 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 điểm gốc trừ phi ứng dụng sửa đổi tư thế đó bằng XRReferenceSpace.getOffsetReferenceSpace(). Mẫu 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

Về mặt lý thuyết, không có gì thay đổi so với những gì tôi đã làm trong phiên thực tế ảo được mô tả trong các bài viết trước đó. 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 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 đối với công nghệ Thực tế tăng cường (AR) hoặc Thực tế ảo (VR). Điều 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 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

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

Ảnh của David Grandmougin trên Unsplash