v147 · Web APIs · WebXR

WebXR plane detection

Chrome 147 ships the WebXR Plane Detection API — a feature that lets AR experiences detect real-world flat surfaces (floors, tables, walls) during a WebXR session, and retrieve their 3D pose and polygon shape in the AR scene.

concepts

  1. Plane Detection Demo

    Requests a WebXR session with the plane-detection feature and shows detected planes as wireframe overlays in the AR view — floor, walls, and furniture surfaces tracked in real time.

  2. Plane Types

    Explains the XRPlane object shape, orientation values (horizontal / vertical), polygon vertices, and how to use planes as placement anchors for virtual objects.

  3. Surface Anchor Manager

    Top-down view of a simulated room with detected planes. Click a surface to attach a virtual object — chairs, tables, lamps, plants — via an XRAnchor. The anchor registry panel updates with each placement, showing how plane-based anchoring works.

  4. Plane Mesh Generator

    Converts an XRPlane.polygon into a WebGL-ready mesh. Paste vertex data or choose a preset room layout. View filled triangulation, wireframe, extruded walls, or convex hull. Drop a collision ball onto the mesh, and export the geometry as GLTF JSON.

  5. Compatibility Lab

    Probes WebXR plane detection globals and immersive-ar session support. Simulates the XRFrame.detectedPlanes data shape — XRPlane.polygon vertex arrays, orientation values, and per-plane pose — to show what your AR app receives on a supporting device.

why it shipped

Plane detection is fundamental to Augmented Reality — knowing where surfaces are lets apps place virtual furniture on a real table, show AR overlays on a real floor, or prevent virtual objects from floating in mid-air. The WebXR Device API provides the underlying AR session; Plane Detection adds the surface recognition layer on top. Chrome 147 brings this to Android Chrome's AR sessions backed by ARCore, making it available to web developers without native app development.

the change

// Request an immersive-ar session with plane detection
const session = await navigator.xr.requestSession('immersive-ar', {
  requiredFeatures: ['plane-detection'],
});

// In the render loop, read detected planes
session.requestAnimationFrame((time, frame) => {
  const detectedPlanes = frame.detectedPlanes; // XRPlaneSet

  for (const plane of detectedPlanes) {
    // plane.orientation: 'horizontal' | 'vertical'
    const pose = frame.getPose(plane.planeSpace, referenceSpace);
    if (!pose) continue;

    // plane.polygon: array of DOMPointReadOnly vertices
    // in the plane's local coordinate system
    const vertices = plane.polygon;
    drawPlaneOutline(pose.transform.matrix, vertices);
  }
});

// Check support before requesting
const supported = await navigator.xr.isSessionSupported('immersive-ar');
const planesSupported = 'detectedPlanes' in XRFrame.prototype;

references

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗