What Web Can Do Today?

Can I rely on the Web Platform features to build my app?

An overview of the device integration HTML5 APIs

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 available vrDevice objects when they have become available.
vrDevice.capabilities
Lists the capabilities of the current VR device, including hasExternalDisplay or canPresent 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 requested mode – either inline (within HTML) or immersive-vr.
navigator.xr.requestSession(mode, options)
Returns a Promise resolved with the AR/VR device session object xrSession after it has been established in requested mode.
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>

Resources

Get in touch