-
-
Notifications
You must be signed in to change notification settings - Fork 36.1k
Description
When calling WebXRManager.setSession( value ) you sometimes might get this message:
Uncaught (in promise) DOMException: Failed to construct 'XRWebGLLayer': WebGL context must be marked as XR compatible in order to use with an immersive XRSession
To Reproduce
I am able to reproduce the issue only on my localhost environment. When serving my viewer from the server it's working fine.
The reason for this issue is a racing condition.
when creating an instance of XRWebGLLayer the WebGL context (gl) should already be XR compatible enabled.
The gl.makeXRCompatible() function returns a Promise.
Current setSession Code
this.setSession = function ( value ) {
session = value;
if ( session !== null ) {
session.addEventListener( 'select', onSessionEvent );
session.addEventListener( 'selectstart', onSessionEvent );
session.addEventListener( 'selectend', onSessionEvent );
session.addEventListener( 'squeeze', onSessionEvent );
session.addEventListener( 'squeezestart', onSessionEvent );
session.addEventListener( 'squeezeend', onSessionEvent );
session.addEventListener( 'end', onSessionEnd );
const attributes = gl.getContextAttributes();
if ( attributes.xrCompatible !== true ) {
gl.makeXRCompatible();
}
const layerInit = {
antialias: attributes.antialias,
alpha: attributes.alpha,
depth: attributes.depth,
stencil: attributes.stencil,
framebufferScaleFactor: framebufferScaleFactor
};
// eslint-disable-next-line no-undef
const baseLayer = new XRWebGLLayer( session, gl, layerInit );
session.updateRenderState( { baseLayer: baseLayer } );
session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace );
//
session.addEventListener( 'inputsourceschange', updateInputSources );
}
};Suggested setSession Code
this.setSession = function ( value ) {
session = value;
if ( session !== null ) {
session.addEventListener( 'select', onSessionEvent );
session.addEventListener( 'selectstart', onSessionEvent );
session.addEventListener( 'selectend', onSessionEvent );
session.addEventListener( 'squeeze', onSessionEvent );
session.addEventListener( 'squeezestart', onSessionEvent );
session.addEventListener( 'squeezeend', onSessionEvent );
session.addEventListener( 'end', onSessionEnd );
const attributes = gl.getContextAttributes();
const setSession = function() {
const layerInit = {
antialias: attributes.antialias,
alpha: attributes.alpha,
depth: attributes.depth,
stencil: attributes.stencil,
framebufferScaleFactor: framebufferScaleFactor
};
// eslint-disable-next-line no-undef
const baseLayer = new XRWebGLLayer( session, gl, layerInit );
session.updateRenderState( { baseLayer: baseLayer } );
session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace );
//
session.addEventListener( 'inputsourceschange', updateInputSources );
};
if ( attributes.xrCompatible !== true ) {
gl.makeXRCompatible( setSession );
} else {
setSession();
}
}
};Platform:
- Device: Mobile (Samsung Galaxy S20 Ultra - Exynos variant)
- OS: Android 11
- Browser: Chrome Canary 89.0.4329.2
- Three.js version: dev, r122
I can create a pull request myself, I just remember that the way to do is on this repo isn't so straghtfarward.
Fork dev?
Build and then push?
If someone wants to do it be my guest. If not, please provide a link or explains how to do it right.
Thanks.
