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

WebGLRenderer: Copy set of layers when copying 3d texture data #29699

Merged
merged 3 commits into from
Oct 20, 2024

Conversation

gkjohnson
Copy link
Collaborator

@gkjohnson gkjohnson commented Oct 19, 2024

Related issue: #29612

Description

Adjust copyTextureToTexture3D to copy each layer between the two 3d textures individually since there is no WebGL method for copying a block of 3d data between textures for render targets.

Tested in my 3d tiles use case and the code is much simpler, now, and it works great. (see #29688)

--

The last piece of the puzzle is copying 2d textures into 3d texture layers along with their mipmaps.

@gkjohnson gkjohnson requested a review from Mugen87 October 19, 2024 10:58

if ( srcTexture.isDepthTexture ) mask = _gl.DEPTH_BUFFER_BIT;

_gl.blitFramebuffer( minX, minY, width, height, dstX, dstY, width, height, mask, _gl.NEAREST );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you completely remove the usage of blitFramebuffer(), the method does not support depth attachments anymore. That means the srcTexture.isDepthTexture should be removed and the documentation should be updated.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to have a depth buffer attachment for a 3d texture?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe so. How would depth testing work otherwise?

Copy link
Collaborator Author

@gkjohnson gkjohnson Oct 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I hadn't really considered the case where you'd be rendering to volume textures that way. I can add it back as an option.

To be clear it doesn't look like the previous code path can ever copy the depth buffer for a color render target in the 2d or 3d case:

let mask = _gl.COLOR_BUFFER_BIT;

if ( srcTexture.isDepthTexture ) mask = _gl.DEPTH_BUFFER_BIT;

The depth component is only copied when isDepthTexture is on the src texture which will never be the case with normal render render targets. We also have no method for creating 3d depth textures. Is this the kind of logic we want instead?

let mask = _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT;

if ( srcTexture.isDepthTexture ) mask = _gl.DEPTH_BUFFER_BIT;

ie just copy all the attached buffers unless it's a depth texture? I feel we might as well just set all the bits anyway regardless of target type when using the blit path.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The depth component is only copied when isDepthTexture is on the src texture which will never be the case with normal render render targets.

We already use the following pattern and it works as expected:

renderer.copyTextureToTexture( this.sampleRenderTarget.depthTexture, this.renderTarget.depthTexture );

I'm okay with keeping the PR as it is and revisit the issue when a developer requests it. For the normal copyTextureToTexture(), the support is critical though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I was confusing myself regarding the depth texture. I've added the same branching logic to choose blit vs copy in both 2d and 3d functions for consistency:

if ( srcTexture.isDepthTexture ) {

	_gl.blitFramebuffer( minX, minY, width, height, dstX, dstY, width, height, _gl.DEPTH_BUFFER_BIT, _gl.NEAREST );

} else {

	_gl.copyTexSubImage2D( _gl.TEXTURE_2D, level, dstX, dstY, minX, minY, width, height );

}

Is the use of copyTextureToTexture for your use case tested in the E2E testing? Or is there an easy way I can test that this code path works for you?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as the original blit is retained for the depth texture, I don't think something should break.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay! In that case this should be ready if it looks good to you.

Copy link

github-actions bot commented Oct 19, 2024

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 692.37
171.33
692.42
171.34
+52 B
+14 B
WebGPU 816.84
220.03
816.84
220.03
+0 B
+0 B
WebGPU Nodes 816.35
219.9
816.35
219.9
+0 B
+0 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 464.59
112.1
464.65
112.12
+52 B
+19 B
WebGPU 538.6
145.39
538.6
145.39
+0 B
+0 B
WebGPU Nodes 494.71
135.27
494.71
135.27
+0 B
+0 B

@gkjohnson gkjohnson merged commit b73e59b into mrdoob:dev Oct 20, 2024
12 checks passed
@gkjohnson gkjohnson deleted the 3d-tex-copy-fix branch October 20, 2024 00:36
@mrdoob mrdoob added this to the r170 milestone Oct 21, 2024
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

Successfully merging this pull request may close these issues.

3 participants