Description
Related: #21734, #29772
It's sometimes necessary to copy the contents of a render target or a depth texture into another one to avoid feedback loops.
Three offers the Renderer.copyTextureToTexture method which supports copying render target textures as well as depth textures. However, this method has a noticable impact on performance when used inside an animation loop because it can't use blitFramebuffer in those cases. It's more suited for infrequent copy operations.
The faster alternative is to use a fullscreen copy pass, but this adds unnecesssary overhead. It's also possible to use blitFramebuffer directly as shown below, but this requires accessing private data and raw gl values.
const gl = renderer.getContext();
const props = renderer.properties;
let blitMask = 0;
if(color) { blitMask |= gl.COLOR_BUFFER_BIT; }
if(depth) { blitMask |= gl.DEPTH_BUFFER_BIT ; }
if(stencil) { blitMask |= gl.STENCIL_BUFFER_BIT; }
const srcFBO = props.get(renderTargetA).__webglFramebuffer;
const dstFBO = props.get(renderTargetB).__webglFramebuffer;
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFBO);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFBO);
gl.blitFramebuffer(
0, 0, renderTargetA.width, renderTargetA.height,
0, 0, renderTargetB.width, renderTargetB.height,
blitMask, gl.NEAREST
);
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
I've done some testing and found that blitFramebuffer is on par with a copy shader while copyTextureToTexture is much slower:
Performance Tests
copy shader

blitFramebuffer

copyTextureToTexture


Solution
It would be great if three had a method equivalent to blitFramebuffer for fast framebuffer copy operations so that users don't have to access internals and use direct gl calls.
Alternatives
copyTextureToTexture could be changed to also accept RenderTarget arguments so that blitFramebuffer can be used internally.
Additional context
I tried using copyTextureToTexture under the assumption that it would use blitFramebuffer internally, but I had to disable it when I noticed the performance degradation.
The use of blitFramebuffer came up again in pmndrs/postprocessing#740.
Description
Related: #21734, #29772
It's sometimes necessary to copy the contents of a render target or a depth texture into another one to avoid feedback loops.
Three offers the Renderer.copyTextureToTexture method which supports copying render target textures as well as depth textures. However, this method has a noticable impact on performance when used inside an animation loop because it can't use
blitFramebufferin those cases. It's more suited for infrequent copy operations.The faster alternative is to use a fullscreen copy pass, but this adds unnecesssary overhead. It's also possible to use
blitFramebufferdirectly as shown below, but this requires accessing private data and raw gl values.I've done some testing and found that
blitFramebufferis on par with a copy shader whilecopyTextureToTextureis much slower:Performance Tests
copy shader
blitFramebuffer
copyTextureToTexture
?blit=1= blitFramebuffer?copyTextureToTexture=1= copyTextureToTextureSolution
It would be great if three had a method equivalent to
blitFramebufferfor fast framebuffer copy operations so that users don't have to access internals and use direct gl calls.Alternatives
copyTextureToTexturecould be changed to also acceptRenderTargetarguments so thatblitFramebuffercan be used internally.Additional context
I tried using copyTextureToTexture under the assumption that it would use
blitFramebufferinternally, but I had to disable it when I noticed the performance degradation.The use of
blitFramebuffercame up again in pmndrs/postprocessing#740.