Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGLRenderTarget: DepthTexture cannot be changed after initial use #19447

Closed
gkjohnson opened this issue May 25, 2020 · 5 comments
Closed

WebGLRenderTarget: DepthTexture cannot be changed after initial use #19447

gkjohnson opened this issue May 25, 2020 · 5 comments
Milestone

Comments

@gkjohnson
Copy link
Collaborator

I'm using a render target depthTexture to render the main scene, then would like to modify the contents of the color buffer without touching the contents of the depth buffer but it looks like once a render target has been set with a given depthTexture setting it cannot be modified later. Here's a simplified example of what I'm trying to do. In practice I'm using multiple textures and a fullscreen quad to render the second time:

const renderTarget = new WebGLRenderTarget();
const depthTexture = new DepthTexture();

// ...

renderTarget.depthTexture = depthTexture;
renderer.setRenderTarget( renderTarget );
renderer.render( scene, camera );

renderTarget.depthTexture = null;
renderer.setRenderTarget( renderTarget );
renderer.render( secondScene, camera );

Looking through the code it looks like these lines are to blame for the depth texture not updating:

if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
textures.setupRenderTarget( renderTarget );
}

textures.setUpRenderTarget will only get called once per render target, which is where the depth texture gets initialized and bound to the frame buffer.

@gkjohnson
Copy link
Collaborator Author

@Mugen87 @mrdoob are there any existing patterns that can be used to fix this? I was looking into how to address it but there are quite a few corner cases.

Here are the cases:

depthBuffer = true, depthTexture = null

  • A rendertarget-specific depth buffer should be created.

depthBuffer = false, depthTexture = null

  • The rendertarget-specific depth buffer should be disposed if it has been created because depthBuffer has been set to false.

depthBuffer = true, depthTexture = DepthTexture instance

  • The depthTexture should be bound as the depth buffer and changed if the depthTexture set is different from the last frame.

depthBuffer = false, depthTexture = DepthTexture instance

  • The depth texture should be unbound but not be disposed.

I wonder if something like the version and needsUpdate pattern might work for renderTargets, too?

@gkjohnson
Copy link
Collaborator Author

FYI for anyone running into this my workaround has been perform a manual copy of the depth textures using the fragDepth extension to retain it when running effects on buffers.

@pailhead
Copy link
Contributor

pailhead commented Jun 4, 2020

I just want to confirm if i understand the example, is what you're trying to achieve possible by turning the depth mask off while rendering to the color attachment?

@gkjohnson
Copy link
Collaborator Author

gkjohnson commented Jun 6, 2020

I just want to confirm if i understand the example, is what you're trying to achieve possible by turning the depth mask off while rendering to the color attachment?

In the above example, yes. Actually not necessarily. But in my work though I was trying to render an effect into another buffer using a fullscreen quad and wanted to move the depthbuffer over so I could draw another mesh without having to do another copy or create a clone of the original depth buffer:

const origTarget = new WebGLRenderTarget( ... );
const effectTarget = new WebGLRenderTarget( ... );
const depthTexture = new DepthTexture();
const effectQuad = new FullScreenQuad( ... );

// ...

origTarget.depthTexture = depthTexture;
renderer.setRenderTarget( origTarget );
renderer.render( scene, camera );

effectQuad.material.uniforms.texture.value = origTarget.texture;
renderer.setRenderTarget( effectTarget );
effectTarget.depthTexture = null;
effectQuad.render( renderer );
effectQuad.depthTexture = depthTexture;

// draw more meshes after the effect has been rendered

@gkjohnson
Copy link
Collaborator Author

Fixed in #28584

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants