BabylonJS/Babylon.js · error
Expected a WebGL graphics binding for WebXR Depth Sensing.
Error message
Expected a WebGL graphics binding for WebXR Depth Sensing.
What it means
attach() for depth sensing retrieves the XR graphics binding from the session manager. Depth sensing with a WebGL-backed WebXR session requires a WebGL graphics binding; if the returned binding's bindingType is not WebGL, Babylon throws this Error. This typically means the session was created with a WebGPU graphics binding, which this path does not support.
Source
Thrown at packages/dev/core/src/XR/features/WebXRDepthSensing.pure.ts:692
return false;
}
this._disableAutoAttachBeforeWebGPUGPUDepth = this._autoAttachPolicyBeforeAttach ?? this.disableAutoAttach;
this._disabledForWebGPUGPUDepth = true;
return this._disableAutoAttach(WebGPUGPUDepthWarning);
}
if (depthUsage == null || depthDataFormat == null) {
return false;
}
if (!super.attach(force)) {
return false;
}
if (!engine.isWebGPU) {
const graphicsBinding = this._xrSessionManager._getGraphicsBinding();
if (graphicsBinding.bindingType !== WebXRGraphicsBindingType.WebGL) {
throw new Error("Expected a WebGL graphics binding for WebXR Depth Sensing.");
}
this._glBinding = graphicsBinding.binding;
}
IsPluginEnabled = !this.options.disableDepthSensingOnMaterials;
if (IsPluginEnabled) {
for (const plugin of ManagedMaterialPlugins) {
plugin.isEnabled = true;
}
this._onCameraObserver = this._xrSessionManager.scene.onBeforeCameraRenderObservable.add((camera) => {
if (!IsPluginEnabled) {
return;
}
// make sure this is a webxr camera
if (camera.outputRenderTarget) {
const viewport = camera.rigCameras.length > 0 ? camera.rigCameras[0].viewport : camera.viewport;
ScreenSize.width = camera.outputRenderTarget.getRenderWidth() / (!engine.isWebGPU && camera.rigParent ? camera.rigParent.rigCameras.length || 1 : 1);
ScreenSize.height = camera.outputRenderTarget.getRenderHeight();
View on GitHub (pinned to 0592b347b8)
Solutions
- Ensure the WebXR session is created with a WebGL graphics binding when using depth sensing with a WebGL engine (align engine and session binding types).
- If using WebGPU, make sure engine.isWebGPU is true so the WebGL-binding check is skipped and the WebGPU path is taken.
- Inspect _xrSessionManager._getGraphicsBinding() before attach to verify bindingType === WebXRGraphicsBindingType.WebGL.
- Avoid custom graphics-binding overrides that return non-WebGL bindings with a WebGL engine.
Example fix
// before
const features = xrSessionManager.enableFeature(WebXRDepthSensing.Name);
// after
const binding = xrSessionManager._getGraphicsBinding();
if (!engine.isWebGPU && binding.bindingType !== WebXRGraphicsBindingType.WebGL) {
throw new Error("Depth sensing requires a WebGL graphics binding with a WebGL engine");
}
const features = xrSessionManager.enableFeature(WebXRDepthSensing.Name); Defensive patterns
Strategy: validation
Validate before calling
const binding = xrSessionManager._getGraphicsBinding();
if (!engine.isWebGPU && binding.bindingType !== WebXRGraphicsBindingType.WebGL) {
throw new Error("Depth sensing requires a WebGL graphics binding with a WebGL engine");
} Type guard
function isWebGLBinding(b: { bindingType: WebXRGraphicsBindingType; binding: unknown }): b is { bindingType: typeof WebXRGraphicsBindingType.WebGL; binding: XRWebGLBinding } {
return b.bindingType === WebXRGraphicsBindingType.WebGL;
} Try / catch
try {
feature.attach();
} catch (e) {
if (String((e as Error).message).includes("Expected a WebGL graphics binding")) {
console.error("Engine/session binding mismatch; re-create session with matching binding");
} else { throw e; }
} Prevention
- Keep engine type and XR session graphics binding consistent (WebGL engine -> WebGL binding)
- Verify bindingType before attaching depth-sensing-dependent features
- Avoid custom _getGraphicsBinding overrides unless types are guaranteed
- Test both WebGPU and WebGL paths when supporting multiple backends
When it happens
Trigger: Attaching the WebXRDepthSensing feature when engine is not WebGPU (isWebGPU false) but the session's graphics binding reports bindingType !== WebXRGraphicsBindingType.WebGL — i.e. a non-WebGL (e.g. WebGPU) binding mismatch, or a custom/unknown binding.
Common situations: Mixed setups where the renderer is WebGL but the XR session manager was configured for WebGPU (or vice versa), custom _getGraphicsBinding overrides returning unexpected binding types, or plugin code expecting WebGL binding only.
Related errors
- Invalid Space Warp framebuffer
- Pausing WebXR depth sensing requires an active XR session.
- XRSession.pauseDepthSensing is not supported by this XR runt
- Resuming WebXR depth sensing requires an active XR session.
- XRSession.resumeDepthSensing is not supported by this XR run
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/017adbc25639e3c2.
Report an issue: GitHub.