-
-
Notifications
You must be signed in to change notification settings - Fork 36.3k
Description
Description
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.



