Trang này sẽ hướng dẫn bạn cách tạo một ứng dụng thực tế tăng cường sống động đơn giản bằng WebXR.
Bạn sẽ cần một môi trường phát triển tương thích với WebXR để bắt đầu.
Tạo trang HTML
WebXR yêu cầu người dùng tương tác để có thể bắt đầu một phiên.
Tạo một nút gọi activateXR()
. Sau khi tải trang, người dùng có thể sử dụng nút này để bắt đầu trải nghiệm AR.
Tạo một tệp mới có tên là index.html
và thêm mã HTML sau vào tệp đó:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Hello WebXR!</title>
<!-- three.js -->
<script src="https://unpkg.com/three@0.126.0/build/three.js"></script>
</head>
<body>
<!-- Starting an immersive WebXR session requires user interaction.
We start this one with a simple button. -->
<button onclick="activateXR()">Start Hello WebXR</button>
<script>
async function activateXR() {
// Add a canvas element and initialize a WebGL context that is compatible with WebXR.
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
const gl = canvas.getContext("webgl", {xrCompatible: true});
// To be continued in upcoming steps.
}
</script>
</body>
</html>
Khởi chạy three.js
Sẽ không có gì xảy ra khi bạn nhấn nút Start (Bắt đầu). Để thiết lập môi trường 3D, bạn có thể sử dụng thư viện kết xuất để hiển thị cảnh.
Trong ví dụ này, bạn sẽ sử dụng three.js
, một thư viện kết xuất 3D JavaScript cung cấp trình kết xuất WebGL. Three.js
xử lý việc kết xuất, máy ảnh và biểu đồ cảnh, giúp bạn dễ dàng hiển thị nội dung 3D trên web.
Tạo cảnh
Môi trường 3D thường được mô hình hoá dưới dạng một cảnh. Tạo một THREE.Scene
chứa các phần tử AR.
Mã sau đây cho phép bạn xem một hộp màu không được chiếu sáng trong AR.
Thêm mã này vào cuối hàm activateXR()
:
const scene = new THREE.Scene();
// The cube will have a different color on each side.
const materials = [
new THREE.MeshBasicMaterial({color: 0xff0000}),
new THREE.MeshBasicMaterial({color: 0x0000ff}),
new THREE.MeshBasicMaterial({color: 0x00ff00}),
new THREE.MeshBasicMaterial({color: 0xff00ff}),
new THREE.MeshBasicMaterial({color: 0x00ffff}),
new THREE.MeshBasicMaterial({color: 0xffff00})
];
// Create the cube and add it to the demo scene.
const cube = new THREE.Mesh(new THREE.BoxBufferGeometry(0.2, 0.2, 0.2), materials);
cube.position.set(1, 1, 1);
scene.add(cube);
Thiết lập tính năng kết xuất bằng three.js
Để có thể xem cảnh này ở chế độ AR, bạn cần có trình kết xuất và máy ảnh. Trình kết xuất sử dụng WebGL để vẽ cảnh của bạn lên màn hình. Máy ảnh mô tả khung nhìn mà cảnh được xem.
Thêm mã này vào cuối hàm activateXR()
:
// Set up the WebGLRenderer, which handles rendering to the session's base layer.
const renderer = new THREE.WebGLRenderer({
alpha: true,
preserveDrawingBuffer: true,
canvas: canvas,
context: gl
});
renderer.autoClear = false;
// The API directly updates the camera matrices.
// Disable matrix auto updates so three.js doesn't attempt
// to handle the matrices independently.
const camera = new THREE.PerspectiveCamera();
camera.matrixAutoUpdate = false;
Tạo XRSession
Điểm truy cập vào WebXR là thông qua XRSystem.requestSession()
. Sử dụng chế độ immersive-ar
để cho phép xem nội dung kết xuất trong môi trường thực tế.
XRReferenceSpace
mô tả hệ toạ độ dùng cho các đối tượng trong thế giới ảo.
Chế độ 'local'
phù hợp nhất với trải nghiệm AR, với không gian tham chiếu có gốc gần người xem và khả năng theo dõi ổn định.
Để tạo XRSession
và XRReferenceSpace
, hãy thêm mã này vào cuối hàm activateXR()
:
// Initialize a WebXR session using "immersive-ar".
const session = await navigator.xr.requestSession("immersive-ar");
session.updateRenderState({
baseLayer: new XRWebGLLayer(session, gl)
});
// A 'local' reference space has a native origin that is located
// near the viewer's position at the time the session was created.
const referenceSpace = await session.requestReferenceSpace('local');
Kết xuất cảnh
Bây giờ, bạn có thể kết xuất cảnh. XRSession.requestAnimationFrame()
lên lịch một lệnh gọi lại được thực thi khi trình duyệt đã sẵn sàng vẽ một khung.
Trong lệnh gọi lại khung ảnh động, hãy gọi XRFrame.getViewerPose()
để lấy tư thế của người xem so với không gian toạ độ cục bộ.
Phương thức này dùng để cập nhật máy ảnh trong cảnh, thay đổi cách người dùng xem thế giới ảo trước khi trình kết xuất vẽ cảnh bằng máy ảnh đã cập nhật.
Thêm mã này vào cuối hàm activateXR()
:
// Create a render loop that allows us to draw on the AR view.
const onXRFrame = (time, frame) => {
// Queue up the next draw request.
session.requestAnimationFrame(onXRFrame);
// Bind the graphics framebuffer to the baseLayer's framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, session.renderState.baseLayer.framebuffer)
// Retrieve the pose of the device.
// XRFrame.getViewerPose can return null while the session attempts to establish tracking.
const pose = frame.getViewerPose(referenceSpace);
if (pose) {
// In mobile AR, we only have one view.
const view = pose.views[0];
const viewport = session.renderState.baseLayer.getViewport(view);
renderer.setSize(viewport.width, viewport.height)
// Use the view's transform matrix and projection matrix to configure the THREE.camera.
camera.matrix.fromArray(view.transform.matrix)
camera.projectionMatrix.fromArray(view.projectionMatrix);
camera.updateMatrixWorld(true);
// Render the scene with THREE.WebGLRenderer.
renderer.render(scene, camera)
}
}
session.requestAnimationFrame(onXRFrame);
Chạy Hello WebXR
Chuyển đến tệp WebXR trên thiết bị. Bạn sẽ có thể xem một khối màu từ mọi phía.
Thêm kiểm thử lượt nhấn
Một cách phổ biến để tương tác với thế giới AR là thông qua kiểm thử va chạm. Phương thức này tìm thấy giao điểm giữa một tia và hình học thực tế. Trong Hello WebXR, bạn sẽ sử dụng kiểm thử lượt nhấn để đặt một hoa hướng dương trong thế giới ảo.
Xoá khối minh hoạ
Xoá khối không sáng và thay thế bằng một cảnh có ánh sáng:
const scene = new THREE.Scene();
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.3);
directionalLight.position.set(10, 15, 10);
scene.add(directionalLight);
Sử dụng tính năng hit-test
Để khởi chạy chức năng kiểm thử lượt nhấn, hãy yêu cầu phiên bằng tính năng hit-test
. Tìm mảnh requestSession()
trước đó rồi thêm hit-test
vào mảnh đó:
const session = await navigator.xr.requestSession("immersive-ar", {requiredFeatures: ['hit-test']});
Thêm trình tải mô hình
Hiện tại, cảnh này chỉ chứa một khối màu. Để trải nghiệm trở nên thú vị hơn, hãy thêm trình tải mô hình cho phép tải mô hình GLTF.
Trong thẻ <head>
của tài liệu, hãy thêm GLTFLoader
của three.js.
<!-- three.js -->
<script src="https://unpkg.com/three@0.126.0/build/three.js"></script>
<script src="https://unpkg.com/three@0.126.0/examples/js/loaders/GLTFLoader.js"></script>
Tải mô hình GLTF
Sử dụng trình tải mô hình từ bước trước để tải một mục tiêu ngắm và một hoa hướng dương từ web.
Thêm mã này vào phía trên onXRFrame
:
const loader = new THREE.GLTFLoader();
let reticle;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/reticle/reticle.gltf", function(gltf) {
reticle = gltf.scene;
reticle.visible = false;
scene.add(reticle);
})
let flower;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/sunflower/sunflower.gltf", function(gltf) {
flower = gltf.scene;
});
// Create a render loop that allows us to draw on the AR view.
const onXRFrame = (time, frame) => {
Tạo nguồn kiểm thử lượt nhấn
Để tính toán các giao điểm với các đối tượng trong thực tế, hãy tạo một XRHitTestSource
bằng cách sử dụng XRSession.requestHitTestSource()
.
Tia sáng dùng để kiểm thử lượt nhấn có không gian tham chiếu viewer
làm gốc, nghĩa là kiểm thử lượt nhấn được thực hiện từ tâm của khung nhìn.
Để tạo nguồn kiểm thử nhấn, hãy thêm mã sau đây sau khi tạo không gian tham chiếu local
:
// A 'local' reference space has a native origin that is located
// near the viewer's position at the time the session was created.
const referenceSpace = await session.requestReferenceSpace('local');
// Create another XRReferenceSpace that has the viewer as the origin.
const viewerSpace = await session.requestReferenceSpace('viewer');
// Perform hit testing using the viewer as origin.
const hitTestSource = await session.requestHitTestSource({ space: viewerSpace });
Vẽ một kim ngắm mục tiêu
Để làm rõ vị trí đặt hoa hướng dương, hãy thêm một mục tiêu ngắm vào cảnh. Dấu ngắm này sẽ xuất hiện trên các bề mặt thực tế, cho biết vị trí đặt hoa hướng dương.
XRFrame.getHitTestResults
trả về một mảng XRHitTestResult
và hiển thị các giao điểm với hình học thực tế.
Sử dụng các giao điểm này để định vị tâm ngắm mục tiêu trên mọi khung hình.
camera.projectionMatrix.fromArray(view.projectionMatrix);
camera.updateMatrixWorld(true);
const hitTestResults = frame.getHitTestResults(hitTestSource);
if (hitTestResults.length > 0 && reticle) {
const hitPose = hitTestResults[0].getPose(referenceSpace);
reticle.visible = true;
reticle.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z)
reticle.updateMatrixWorld(true);
}
Thêm lượt tương tác khi nhấn
XRSession
nhận các sự kiện select
khi người dùng hoàn tất một hành động chính.
Trong một phiên AR, thao tác này tương ứng với một lần nhấn vào màn hình.
Tạo một hoa hướng dương mới xuất hiện khi người dùng nhấn vào màn hình bằng cách thêm mã này trong quá trình khởi chạy:
let flower;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/sunflower/sunflower.gltf", function(gltf) {
flower = gltf.scene;
});
session.addEventListener("select", (event) => {
if (flower) {
const clone = flower.clone();
clone.position.copy(reticle.position);
scene.add(clone);
}
});
Kiểm thử thử nghiệm nhấn
Sử dụng thiết bị di động để chuyển đến trang đó. Sau khi WebXR hiểu được môi trường, đường ngắm sẽ xuất hiện trên các bề mặt thực tế. Nhấn vào màn hình để đặt một bông hướng dương có thể xem được từ mọi phía.
Các bước tiếp theo
- Đọc Quy cách API thiết bị WebXR.
- Hãy xem tài liệu tham khảo WebXR trên tài liệu web của MDN.
- Dùng thử Mẫu WebXR.
- Tạo ứng dụng thực tế tăng cường (AR) bằng WebXR Device API (lớp học lập trình).