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
-
Plane Detection Demo
Requests a WebXR session with the
plane-detectionfeature and shows detected planes as wireframe overlays in the AR view — floor, walls, and furniture surfaces tracked in real time. -
Plane Types
Explains the
XRPlaneobject shape, orientation values (horizontal/vertical), polygon vertices, and how to use planes as placement anchors for virtual objects. -
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. -
Plane Mesh Generator
Converts an
XRPlane.polygoninto 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. -
Compatibility Lab
Probes WebXR plane detection globals and
immersive-arsession support. Simulates theXRFrame.detectedPlanesdata shape —XRPlane.polygonvertex arrays,orientationvalues, 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 ↗