WebXR Layers API
More actions
The WebXR Layers API extends WebXR with separate composition layers for immersive sessions. An application can submit a rendered 3D scene alongside panels, curved surfaces or environment images, which the XR compositor combines for presentation.[1]
As of 21 October 2026, WebXR Layers API Level 1 was a W3C Working Draft dated 11 August 2026. The Immersive Web Working Group published its First Public Working Draft on 3 December 2020. It had not reached W3C Recommendation status.[2]
Rendering model
In the core WebXR rendering path, an XRWebGLLayer connects an XR session to a WebGL context. It supplies a framebuffer and the viewport for each view, allowing the application to render the views into the appropriate portions of that framebuffer.[3] With composition layers, an application can instead keep some imagery separate from this eye buffer. Meta's implementation guide uses a skybox, video and interactive foreground as an example: the compositor handles the background and video separately while WebGL renders the changing foreground.[4]
This separation can avoid sampling an image into the eye buffer and then sampling the result again during composition. A static background can remain available to the compositor without being redrawn by the application for every display frame. These are reasons to use layers for high-resolution imagery and text; the savings depend on the content and rendering path.[4] Separate resolutions allow a detailed text panel alongside a lower-resolution main scene. The explainer describes potential improvements to judder and latency through compositor reprojection, rather than a fixed performance result for every application.[1]
Layer types
XRWebGLBinding creates GPU-backed layers for an XR session and WebGL context. Its creation methods cover five composition-layer types.[5]
| Interface | Presentation |
|---|---|
XRProjectionLayer |
Fills the observer's view with application-rendered imagery. Unlike a positioned panel, it has no associated XRSpace.[6]
|
XRQuadLayer |
A flat rectangle positioned and oriented in 3D space. It has no thickness, and only its front is visible.[7] |
XRCylinderLayer |
A curved rectangular surface.[5] |
XREquirectLayer |
Maps equirectangular imagery onto the inside of a sphere.[5] |
XRCubeLayer |
Uses a cubemap projected onto the inside faces of a cube.[5] |
A quad's space establishes its spatial relationship to the environment, and its transform supplies an offset and orientation within that space. Width and height describe its physical size in meters, separately from the resolution of its image.[7] This distinguishes the placement and dimensions of a virtual panel from the number of pixels used to draw it.
Session setup and rendering
The August 2026 draft restricts layers to immersive-vr and immersive-ar sessions; inline sessions cannot use them. Non-projection composition layers require the layers feature to be enabled through the session's requiredFeatures or optionalFeatures request. A single projection layer can be used without that feature; submitting more than one layer still requires it.[8]
After creating the layers, the application passes an ordered layers array to XRSession.updateRenderState(). The update is scheduled for a subsequent frame. This replaces the session's baseLayer, which then reports null; supplying both properties in one update is rejected. The array normally specifies back-to-front composition, so a later entry can cover an earlier one. Duplicate layer instances are rejected.[9]
Rendering uses the binding to obtain the appropriate image resources. getViewSubImage() supplies a projection layer's render target for an XRView, while getSubImage() serves other composition layers.[5] The returned subimage identifies the texture and viewport. Texture-array rendering also uses an image index to select the array slice. These textures have restricted access and lifetime within XR frame processing; they are not ordinary application-owned textures that can be read or used at arbitrary times.[1]
Video layers
XRMediaBinding creates quad, cylinder and equirectangular layers from an HTMLVideoElement. The layer displays the video's frames. It does not include the video's playback controls, which need a separate interface.[10] Playback still uses the video element's normal methods. The layer layout can identify stereoscopic imagery packed side by side or top to bottom, allowing the appropriate portion to reach each eye.[1]
This provides a route for presenting 360-degree video without manually copying each decoded video frame into the application's scene texture. Meta documents media layers alongside its compositor-backed WebXR layers implementation.[4]
Redrawing, ordering and resource limits
The shared XRCompositionLayer interface provides properties such as texture-alpha blending, layout and needsRedraw. The latter signals that content needs rendering in the next frame. Its destroy() method releases underlying layer attachments.[11] A quad can also receive a redraw event when resources are lost or the compositor can no longer reproject its image. Static content therefore still needs a path for restoring its imagery.[7]
Array ordering does not automatically give separately submitted surfaces the same occlusion behavior as objects rendered together. The August 2026 draft adds the optional depth-sorted-layers feature for depth ordering of projection, quad and cylinder layers. Other layer types retain array ordering. The browser may limit layer counts and pixel allocations, including for privacy reasons.[8]
Implementation and fallback
Availability must be checked for the target browser and device. MDN marks the WebGL and media binding interfaces as experimental and of limited availability, and documents secure-context requirements.[5][10] The draft's mandatory projection-layer behavior describes conforming implementations of the module; it does not establish that every browser with WebXR implements the module.[8]
The Immersive Web project's WebXR Layers Polyfill implements layers in JavaScript and WebGL. It renders their contents into an internal baseLayer, which is then presented through the existing WebXR path. This offers API emulation rather than a separate native compositor path. Its documented omissions include non-projection onredraw events, mip-level handling and secondary projection views.[12] Applications therefore need to distinguish API availability, supported layer types and the capabilities of the actual rendering implementation.
References
- ↑ 1.0 1.1 1.2 1.3 "Layers in WebXR". Immersive Web. https://github.com/immersive-web/layers/blob/main/explainer.md. Retrieved 2026-10-21.
- ↑ "WebXR Layers API Level 1 publication history". W3C. https://www.w3.org/standards/history/webxrlayers-1/. Retrieved 2026-10-21.
- ↑ "XRWebGLLayer". MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/XRWebGLLayer. Retrieved 2026-10-21.
- ↑ 4.0 4.1 4.2 "WebXR Layers". Meta Horizon OS Developers. https://developers.meta.com/horizon/documentation/web/webxr-layers/. Retrieved 2026-10-21.
- ↑ 5.0 5.1 5.2 5.3 5.4 5.5 "XRWebGLBinding". MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/XRWebGLBinding. Retrieved 2026-10-21.
- ↑ "XRProjectionLayer". MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/XRProjectionLayer. Retrieved 2026-10-21.
- ↑ 7.0 7.1 7.2 "XRQuadLayer". MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/XRQuadLayer. Retrieved 2026-10-21.
- ↑ 8.0 8.1 8.2 "WebXR Layers API Level 1". W3C. 2026-08-11. https://www.w3.org/TR/2026/WD-webxrlayers-1-20260811/. Retrieved 2026-10-21.
- ↑ "XRSession: updateRenderState() method". MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/XRSession/updateRenderState. Retrieved 2026-10-21.
- ↑ 10.0 10.1 "XRMediaBinding". MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/XRMediaBinding. Retrieved 2026-10-21.
- ↑ "XRCompositionLayer". MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/XRCompositionLayer. Retrieved 2026-10-21.
- ↑ "WebXR Layers Polyfill". Immersive Web. https://github.com/immersive-web/webxr-layers-polyfill. Retrieved 2026-10-21.