From 6fcc61aaf460825114a72e65d3a4dc3d8b99e2af Mon Sep 17 00:00:00 2001 From: Rik Cabanier Date: Fri, 30 May 2025 08:18:48 +0000 Subject: [PATCH 1/2] silence opaque framebuffer warning --- src/renderers/common/XRManager.js | 1 + src/renderers/webgl-fallback/WebGLBackend.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/renderers/common/XRManager.js b/src/renderers/common/XRManager.js index 217851c5936b7b..72a341e10a38d7 100644 --- a/src/renderers/common/XRManager.js +++ b/src/renderers/common/XRManager.js @@ -1036,6 +1036,7 @@ class XRManager extends EventDispatcher { } ); + this._xrRenderTarget._isOpaqueFramebuffer = true; this._referenceSpace = await session.requestReferenceSpace( this.getReferenceSpaceType() ); } diff --git a/src/renderers/webgl-fallback/WebGLBackend.js b/src/renderers/webgl-fallback/WebGLBackend.js index 58c65fdac39634..3984412cb3d94d 100644 --- a/src/renderers/webgl-fallback/WebGLBackend.js +++ b/src/renderers/webgl-fallback/WebGLBackend.js @@ -2171,7 +2171,7 @@ class WebGLBackend extends Backend { // rebind external XR textures - if ( isXRRenderTarget || useMultisampledRTT || renderTarget.multiview ) { + if ( ( isXRRenderTarget || useMultisampledRTT || renderTarget.multiview ) && ( renderTarget._isOpaqueFramebuffer !== true ) ) { state.bindFramebuffer( gl.FRAMEBUFFER, fb ); From aae0c204dea13456111451c96aae0d024f017e8d Mon Sep 17 00:00:00 2001 From: Rik Cabanier Date: Fri, 30 May 2025 17:35:12 +0000 Subject: [PATCH 2/2] address review comments --- src/renderers/common/Renderer.js | 2 +- src/renderers/common/XRManager.js | 8 +++---- src/renderers/common/XRRenderTarget.js | 22 ++++++++++++++++---- src/renderers/webgl-fallback/WebGLBackend.js | 16 +++++++------- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index e2ee9095e9ba63..c06fe9b02d4c94 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -1260,7 +1260,7 @@ class Renderer { frameBufferTarget.scissorTest = this._scissorTest; frameBufferTarget.multiview = outputRenderTarget !== null ? outputRenderTarget.multiview : false; frameBufferTarget.resolveDepthBuffer = outputRenderTarget !== null ? outputRenderTarget.resolveDepthBuffer : true; - frameBufferTarget.autoAllocateDepthBuffer = outputRenderTarget !== null ? outputRenderTarget.autoAllocateDepthBuffer : false; + frameBufferTarget._autoAllocateDepthBuffer = outputRenderTarget !== null ? outputRenderTarget._autoAllocateDepthBuffer : false; return frameBufferTarget; diff --git a/src/renderers/common/XRManager.js b/src/renderers/common/XRManager.js index 72a341e10a38d7..67feb75ed4c62e 100644 --- a/src/renderers/common/XRManager.js +++ b/src/renderers/common/XRManager.js @@ -641,7 +641,7 @@ class XRManager extends EventDispatcher { resolveStencilBuffer: false } ); - renderTarget.autoAllocateDepthBuffer = true; + renderTarget._autoAllocateDepthBuffer = true; const material = new MeshBasicMaterial( { color: 0xffffff, side: FrontSide } ); material.map = renderTarget.texture; @@ -732,7 +732,7 @@ class XRManager extends EventDispatcher { resolveStencilBuffer: false } ); - renderTarget.autoAllocateDepthBuffer = true; + renderTarget._autoAllocateDepthBuffer = true; const material = new MeshBasicMaterial( { color: 0xffffff, side: BackSide } ); material.map = renderTarget.texture; @@ -806,7 +806,7 @@ class XRManager extends EventDispatcher { for ( const layer of this._layers ) { layer.renderTarget.isXRRenderTarget = this._session !== null; - layer.renderTarget.hasExternalTextures = layer.renderTarget.isXRRenderTarget; + layer.renderTarget._hasExternalTextures = layer.renderTarget.isXRRenderTarget; if ( layer.renderTarget.isXRRenderTarget && this._supportsLayers ) { @@ -974,7 +974,7 @@ class XRManager extends EventDispatcher { multiview: this._useMultiview } ); - this._xrRenderTarget.hasExternalTextures = true; + this._xrRenderTarget._hasExternalTextures = true; this._xrRenderTarget.depth = this._useMultiview ? 2 : 1; this._supportsLayers = session.enabledFeatures.includes( 'layers' ); diff --git a/src/renderers/common/XRRenderTarget.js b/src/renderers/common/XRRenderTarget.js index 21503a261cfbea..2b7e6cf7f69f94 100644 --- a/src/renderers/common/XRRenderTarget.js +++ b/src/renderers/common/XRRenderTarget.js @@ -37,7 +37,7 @@ class XRRenderTarget extends RenderTarget { * @type {boolean} * @default false */ - this.hasExternalTextures = false; + this._hasExternalTextures = false; /** * Whether a depth buffer should automatically be allocated @@ -53,7 +53,21 @@ class XRRenderTarget extends RenderTarget { * @type {boolean} * @default true */ - this.autoAllocateDepthBuffer = true; + this._autoAllocateDepthBuffer = true; + + + /** + * Whether this render target is associated with a XRWebGLLayer. + * + * A XRWebGLLayer points to an opaque framebuffer. Basically, + * this means that you don't have access to its bound color, + * stencil and depth buffers. We need to handle this framebuffer + * differently since its textures are always bound. + * + * @type {boolean} + * @default false + * */ + this._isOpaqueFramebuffer = false; } @@ -61,8 +75,8 @@ class XRRenderTarget extends RenderTarget { super.copy( source ); - this.hasExternalTextures = source.hasExternalTextures; - this.autoAllocateDepthBuffer = source.autoAllocateDepthBuffer; + this._hasExternalTextures = source._hasExternalTextures; + this._autoAllocateDepthBuffer = source._autoAllocateDepthBuffer; return this; diff --git a/src/renderers/webgl-fallback/WebGLBackend.js b/src/renderers/webgl-fallback/WebGLBackend.js index 3984412cb3d94d..b7af7e9f5aca1c 100644 --- a/src/renderers/webgl-fallback/WebGLBackend.js +++ b/src/renderers/webgl-fallback/WebGLBackend.js @@ -364,13 +364,13 @@ class WebGLBackend extends Backend { // The multisample_render_to_texture extension doesn't work properly if there // are midframe flushes and an external depth texture. - if ( ( this.extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) && renderTarget.autoAllocateDepthBuffer === true && renderTarget.multiview === false ) { + if ( ( this.extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) && renderTarget._autoAllocateDepthBuffer === true && renderTarget.multiview === false ) { console.warn( 'THREE.WebGLBackend: Render-to-texture extension was disabled because an external texture was provided' ); } - renderTarget.autoAllocateDepthBuffer = false; + renderTarget._autoAllocateDepthBuffer = false; } @@ -2002,7 +2002,7 @@ class WebGLBackend extends Backend { const isRenderTarget3D = renderTarget.isRenderTarget3D === true; const isRenderTargetArray = renderTarget.depth > 1; const isXRRenderTarget = renderTarget.isXRRenderTarget === true; - const hasExternalTextures = ( isXRRenderTarget === true && renderTarget.hasExternalTextures === true ); + const _hasExternalTextures = ( isXRRenderTarget === true && renderTarget._hasExternalTextures === true ); let msaaFb = renderTargetContextData.msaaFrameBuffer; let depthRenderbuffer = renderTargetContextData.depthRenderbuffer; @@ -2019,7 +2019,7 @@ class WebGLBackend extends Backend { fb = renderTargetContextData.cubeFramebuffers[ cacheKey ]; - } else if ( isXRRenderTarget && hasExternalTextures === false ) { + } else if ( isXRRenderTarget && _hasExternalTextures === false ) { fb = this._xrFramebuffer; @@ -2095,7 +2095,7 @@ class WebGLBackend extends Backend { const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - if ( renderTarget.autoAllocateDepthBuffer === true ) { + if ( renderTarget._autoAllocateDepthBuffer === true ) { const renderbuffer = gl.createRenderbuffer(); this.textureUtils.setupRenderBufferStorage( renderbuffer, descriptor, 0, useMultisampledRTT ); @@ -2120,7 +2120,7 @@ class WebGLBackend extends Backend { multiviewExt.framebufferTextureMultisampleMultiviewOVR( gl.FRAMEBUFFER, depthStyle, textureData.textureGPU, 0, samples, 0, 2 ); - } else if ( hasExternalTextures && useMultisampledRTT ) { + } else if ( _hasExternalTextures && useMultisampledRTT ) { multisampledRTTExt.framebufferTexture2DMultisampleEXT( gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0, samples ); @@ -2197,7 +2197,7 @@ class WebGLBackend extends Backend { const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - if ( renderTarget.autoAllocateDepthBuffer === true ) { + if ( renderTarget._autoAllocateDepthBuffer === true ) { const renderbuffer = renderTargetContextData.xrDepthRenderbuffer; gl.bindRenderbuffer( gl.RENDERBUFFER, renderbuffer ); @@ -2528,7 +2528,7 @@ class WebGLBackend extends Backend { } - return renderTarget.samples > 0 && this.extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true && renderTarget.autoAllocateDepthBuffer !== false; + return renderTarget.samples > 0 && this.extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true && renderTarget._autoAllocateDepthBuffer !== false; }