three
Version:
JavaScript 3D library
90 lines (51 loc) • 2.38 kB
JavaScript
/**
* Sets up a construction-time WebGL fallback for WebGPU XR examples.
*
* @param {WebGPURenderer} renderer - The initial renderer.
* @param {Function} createFallbackRenderer - A function that returns a new renderer with a WebGL backend.
* @param {Function} onFallback - A function that installs the new renderer in the app.
*/
function setupWebGLXRFallback( renderer, createFallbackRenderer, onFallback = () => {} ) {
let currentRenderer = renderer;
const patchedRenderers = new WeakSet();
function patchRenderer( renderer ) {
if ( patchedRenderers.has( renderer ) ) return;
patchedRenderers.add( renderer );
const setSession = renderer.xr.setSession.bind( renderer.xr );
renderer.xr.setSession = async function ( session ) {
if ( renderer !== currentRenderer ) {
return currentRenderer.xr.setSession( session );
}
if ( session !== null && renderer.backend.isWebGPUBackend === true && session.enabledFeatures.includes( 'webgpu' ) === false ) {
return switchToFallbackRenderer( session, renderer );
}
try {
return await setSession( session );
} catch ( error ) {
if ( session === null || renderer.backend.isWebGPUBackend !== true ) {
throw error;
}
return switchToFallbackRenderer( session, renderer );
}
};
}
async function switchToFallbackRenderer( session, renderer ) {
if ( renderer.initialized === false ) await renderer.init();
const fallbackRenderer = createFallbackRenderer( renderer );
if ( fallbackRenderer.backend.isWebGLBackend !== true ) {
throw new Error( 'THREE.WebGLXRFallback: createFallbackRenderer() must return a renderer with a WebGL backend.' );
}
const animationLoop = renderer.getAnimationLoop();
fallbackRenderer.xr.enabled = renderer.xr.enabled;
fallbackRenderer.xr.cameraAutoUpdate = renderer.xr.cameraAutoUpdate;
fallbackRenderer.xr.setFramebufferScaleFactor( renderer.xr.getFramebufferScaleFactor() );
fallbackRenderer.xr.setReferenceSpaceType( renderer.xr.getReferenceSpaceType() );
if ( animationLoop !== null ) await fallbackRenderer.setAnimationLoop( animationLoop );
await onFallback( fallbackRenderer, renderer );
currentRenderer = fallbackRenderer;
patchRenderer( fallbackRenderer );
return fallbackRenderer.xr.setSession( session );
}
patchRenderer( renderer );
}
export { setupWebGLXRFallback };