Virtual & Augmented Reality
The support for Virtual and Augmented Reality for the Web applications as of early 2020 is limited and inconsistent. There are two APIs available. The older one - WebVR API - is available in some browsers for some particular VR environments. The newer one - WebXR Device API - which tries to approach the topic in a more generic fashion, including AR or Mixed Reality devices, is being deployed in Chromium-based browsers starting late 2019.
Both APIs share the same fundamental concepts. Their scope is to allow authorized Web applications to discover available VR/AR devices, establish a session with the device, read the device-specific geometry data required to prepare the proper rendering and bind a <canvas>
element as a visual layer onto the device.
This way the rendering details are handled by the existing canvas interfaces like WebGL context and the implementors very often delegate the rendering itself to the specialized libraries like A-Frame.
API glimpse
Older WebVR API
navigator.getVRDisplays()
- Returns a
Promise
resolved with the list of availablevrDevice
objects when they have become available. vrDevice.capabilities
- Lists the capabilities of the current VR device, including
hasExternalDisplay
orcanPresent
boolean flags. vrDevice.requestPresent(layers)
- Requests putting the specified visual layers onto VR device's display and starts a session with the device. A layer might be represented by an object containing canvas rendering context that defines the rendering that will be presented (
{source: canvasContext}
). vrDevice.getFrameData(frameData)
- Fills the passed
frameData
object with the projection matrices needed to render a frame. vrDevice.requestAnimationFrame(callback)
- Registers a
callback
that will be executed within the next rendering frame on the VR device. vrDevice.submitFrame()
- Indicates that the layers canvases are ready to be rendered as a frame on the VR device.
vrDevice.exitPresent()
- Requests finishing the current session. Returns a
Promise
resolved when the VR session is finished.
Newer WebXR Device API
navigator.xr.isSessionSupported(mode)
- Returns a
Promise
resolved with a flag whether the device allows sessions of requestedmode
– eitherinline
(within HTML) orimmersive-vr
. navigator.xr.requestSession(mode, options)
- Returns a
Promise
resolved with the AR/VR device session objectxrSession
after it has been established in requestedmode
. xrSession.requestReferenceSpace(type)
- Returns a
Promise
resolved with the reference space that provides a coordinate system for the requested type. xrSession.updateRenderState(state)
- Updates the render state to be applied on the next rendering frame, potentially changing the base WebGL layer.
xrSession.requestAnimationFrame(callback)
- Registers a
callback
that will be executed within the next rendering frame within the AR/VR session. xrSession.end()
- Requests finishing the current session. Returns a
Promise
resolved when the AR/VR session is finished.
Live Demo
-
document.getElementById('startVRButton').addEventListener('click', function () { if (navigator.xr) { checkForXR(); } else if (navigator.getVRDisplays) { checkForVR(); } else { alert('WebXR/WebVR APIs are not supported.'); } }); async function checkForXR() { if (!await navigator.xr.isSessionSupported('immersive-vr')) { alert('No immersive VR device detected'); return; } const session = await navigator.xr.requestSession('immersive-vr'); if (!session.inputSources.length) { throw 'VR supported, but no VR input sources available'; } const result = document.getElementById('result'); result.innerHTML = session.inputSources.length + ' input sources detected'; } async function checkForVR() { try { const displays = await navigator.getVRDisplays() if (!displays.length) { throw 'VR supported, but no VR displays available'; } const result = document.getElementById('result'); displays.forEach(function (display) { let li = document.createElement('li'); li.innerHTML = display.displayName + ' (' + display.displayId + ')'; result.appendChild(li); }) } catch (err) { alert(err); } }
-
<p><button type="button" id="startVRButton">Check for VR device</button></p> <ul id="result"></ul> <p> <a href="https://immersive-web.github.io/webxr-samples/" target="_blank" rel="noopener">Browse WebXR samples</a><br/> <a href="https://mixedreality.mozilla.org/mobile/" target="_blank" rel="noopener">Browse demos by Mozilla</a> </p>