The spec is finally moving. The WebXR/WebGPU Binding is now an official Immersive Web Editor’s Draft (dated 15 June 2026). It defines XRGPUBinding where you request an xrCompatible GPUDevice and create WebGPU-backed projection/composition layers instead of XRWebGLLayer. After ~3 years of the proposal sitting dead, it’s active again, largely because Quest Browser shipping WebGPU made it worth doing. As a result, can we expect Babylon to enable a WebGPU backend for immersive mode sometime in the near future? ![]()
Things are happening. I will keep you updated about the WebGPU support.
Oh, the link of the proposal has been updated to below I think:
Yup, we are actively connected with the spec ppl there ![]()
If anyone wants to track the work - [Epic] WebGPU support for WebXR · Issue #18635 · BabylonJS/Babylon.js · GitHub
Experimental on the quest browser is more than enough to start playing around with it ![]()
Will this help unlock WebXR support for Babylon Lite?
Of course. WebXR for lite is already partly implemented, but will stay experimental for a long time because of the lack of WebGPU support in most browsers. It is not yet commited and there are still things to be fixed. But know that I am working on it.
What all has to be done to check and set up WebGPU with WebXR if it is fully supported (and fall back to WebGL?)
I’ve attempted to create a Playground, but haven’t figured out how even to get ordinary WebGPU running in the Playground — my latest attempt is
export const createEngine = async function () {
const cvs = (typeof canvas !== "undefined" && canvas) || document.querySelector("canvas");
let supported = false;
try {
supported = !!(BABYLON.WebGPUEngine && (await BABYLON.WebGPUEngine.IsSupportedAsync));
} catch (e) {
console.error(e);
}
if (supported) {
try {
const wgpu = new BABYLON.WebGPUEngine(cvs, { xrCompatible: true, antialias: true });
await wgpu.initAsync();
return wgpu;
} catch (e) {
console.error(e);
}
}
const gl = new BABYLON.Engine(cvs, true, { preserveDrawingBuffer: true, stencil: true, xrCompatible: true });
return gl;
};
based on https://playground.babylonjs.com/#55MXDY#0
Based on Babylon.js docs the code in my app checks both WebGPUEngine.IsSupportedAsync and `const isXRLayersSupported = WebXRFeaturesManager.GetAvailableFeatures().includes(WebXRFeatureName.LAYERS);`
async function createEngineForImmersiveXR(canvas: HTMLCanvasElement, isXRLayersSupported: boolean, willUseXR: boolean) : Promise<WebGPUEngine | Engine> {
const webGPUSupported = await WebGPUEngine.IsSupportedAsync;
// Includes XRGPUBinding projection APIs and XRGPUSubImage.getViewDescriptor.
// @ts-ignore
const webGPUXRSupported = WebXRSessionManager.IsWebGPUXRSupported;
console.log(`isXRLayersSupported`, isXRLayersSupported, `willUseXR`, willUseXR, `webGPUSupported`, webGPUSupported, `webGPUXRSupported`, webGPUXRSupported);
dialog.show(`isXRLayersSupported ${isXRLayersSupported}\nwillUseXR ${willUseXR}\nwebGPUSupported ${webGPUSupported}\nwebGPUXRSupported ${webGPUXRSupported}`);
if (webGPUSupported && (willUseXR ? webGPUXRSupported && isXRLayersSupported : true)) {
let engine: WebGPUEngine;
try {
console.log(`new WebGPU options:`, { xrCompatible: willUseXR && webGPUXRSupported && isXRLayersSupported });
engine = new WebGPUEngine(canvas, { xrCompatible: willUseXR && webGPUXRSupported && isXRLayersSupported });
await engine.initAsync();
return engine;
} catch (error) {
// @ts-ignore
engine?.dispose();
console.warn("failed to initialize an XR-compatible WebGPU engine; using WebGL instead:", error);
const msgs = errToMessages(error as ErrorLike, new Set(["failed to initialize an XR-compatible WebGPU engine"]));
for (let msg of msgs) {
dialog.show(msg);
}
}
}
return new Engine(canvas, true, {xrCompatible: willUseXR});
}
When the system supports WebGPU but not WebGL, this creates a WebGPU engine that works fine.
With this, I can create a default WebXRExperience, which runs in flat mode (and in immersive modes when a WebGL engine is selected), but when webGPUSupported, `webGPUXRSupportedandisXRLayersSupported` are all true, I click the button to go into immersive-ar or immersive-vr mode, it fails and this is logged to the console:
BJS - [15:46:07]: Error: One or more required features are not supported by the device.
logger.js:52 BJS - [15:46:07]: One or more required features are not supported by the device.
thanks, I will look into that!
FWIW, it’s pretty tricky and it took me a few days in my BabylonNative wgpu branch to get my Factotum WebXR app launching and working in WebXR-on-WebGPU across Pico, Quest, HTC, and Apple Vision Pro. Pro tip: for lower-end Qualcomm XR2 gen 1 devices, and for AR on iPhone XR, the WebGPU feature multi-draw indirect is an absolute necessity. Even on Qualcomm XR Elite, it helps keep CPU clocks lower which helps with thermals and battery life while maintaining 72-90fps.
Is it possible to enable that in a webapp? I can set enableIndirectDraw in the WebGPUEngine constructor arguments, but I’m not seeing that multi-draw indirect is available.
the underlying WebGPU implementation has to have the feature enabled on the given adapter. my wgpu branch of BabylonNative is building against a PR branch of wgpu itself: use Metal's Indirect Command Buffers for true GPU-side multi draw indirect by matthargett · Pull Request #9640 · gfx-rs/wgpu · GitHub . the nice thing with BabylonNative is that we can build beyond the edge of the current desktop browser uptake of recent standards work ![]()
I notice with the browser flag for GPU bindings on, XR is working well on the latest Blink distros.
Appreciate @RaananW et al. for that. That was my main hesitancy from Lite.