WebXR Device API
The WebXR Device API provides access to input and output capabilities commonly associated with Virtual Reality (VR) and Augmented Reality (AR) hardware. It allows you to create immersive 3D experiences directly in the browser.
1. The Concept
WebXR replaces the older WebVR API. It is designed to handle both VR (replacing the user's view entirely) and AR (overlaying digital content onto the real world).
- VR (Virtual Reality): Opaque headsets (Oculus, Vive).
- AR (Augmented Reality): Transparent headsets (HoloLens) or phone cameras (mobile AR).
2. Checking Support
You access the API via navigator.xr. You should check if a specific mode is supported before offering it to the user.
if (navigator.xr) {
navigator.xr.isSessionSupported('immersive-vr')
.then((isSupported) => {
if (isSupported) {
console.log('VR is supported!');
// Enable VR button
}
});
}
Modes: 'inline', 'immersive-vr', 'immersive-ar'.
3. Requesting a Session
To start an experience, you request a session. This usually requires a user gesture.
let xrSession = null;
async function onEnterVR() {
if (!xrSession) {
xrSession = await navigator.xr.requestSession('immersive-vr', {
requiredFeatures: ['local-floor']
});
// Set up the session
xrSession.addEventListener('end', onSessionEnded);
// Create a WebGL context and set it as the base layer
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl', { xrCompatible: true });
xrSession.updateRenderState({
baseLayer: new XRWebGLLayer(xrSession, gl)
});
// Start the render loop
xrSession.requestAnimationFrame(onXRFrame);
}
}
4. The Render Loop
Unlike standard web apps which use window.requestAnimationFrame, WebXR apps use session.requestAnimationFrame. The callback receives a timestamp and an XRFrame object.
function onXRFrame(time, frame) {
const session = frame.session;
// Queue the next frame
session.requestAnimationFrame(onXRFrame);
// Get the pose (position and orientation) of the viewer
const referenceSpace = /* ... obtained earlier ... */;
const pose = frame.getViewerPose(referenceSpace);
if (pose) {
const glLayer = session.renderState.baseLayer;
// Bind the framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, glLayer.framebuffer);
// Clear the canvas
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Loop through views (eyes)
for (const view of pose.views) {
const viewport = glLayer.getViewport(view);
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
// Draw your 3D scene here using view.projectionMatrix and view.transform
// drawScene(view);
}
}
}
5. Reference Spaces
Reference spaces define the coordinate system for the tracking.
local: For seated experiences. Origin is where the user's head was when the session started.local-floor: For standing experiences. Origin is on the floor.viewer: Origin tracks the viewer's head (useful for inline or HUDs).unbounded: For large areas (walking around a room).
// Inside the session setup
const referenceSpace = await xrSession.requestReferenceSpace('local-floor');
programming/javascript/vanilla/javascript programming/javascript/vanilla/canvas-api programming/javascript/vanilla/promises-async-await