Skip to content

WebGPURenderer: Use depth32float instead of depth24plus when using reversedDepthBuffer#33184

Merged
Mugen87 merged 8 commits into
mrdoob:devfrom
PoseidonEnergy:fix/firefox-webgpu
Mar 16, 2026
Merged

WebGPURenderer: Use depth32float instead of depth24plus when using reversedDepthBuffer#33184
Mugen87 merged 8 commits into
mrdoob:devfrom
PoseidonEnergy:fix/firefox-webgpu

Conversation

@PoseidonEnergy

@PoseidonEnergy PoseidonEnergy commented Mar 15, 2026

Copy link
Copy Markdown
Contributor

Fixed #33166

Description

This PR makes WebGPU use depth32float when reversedDepthBuffer is enabled.

Right now, PassNode creates a DepthTexture for its internal RenderTarget, but it leaves the depth texture on the default type. The WebGPU format mapping already supports DepthFormat + FloatType -> Depth32Float, but the default non-stencil canvas path and the pipeline format query still use Depth24Plus.

This fixes the Firefox webgpu_reversed_depth_buffer z-fighting issue: the example itself already notes that "for best results, a floating-point depth buffer should be used," and explicitly using float depth removes the remaining z-fighting seen in Firefox for the reverse-Z column.

@Mugen87

Mugen87 commented Mar 15, 2026

Copy link
Copy Markdown
Collaborator

I understand the PR aligns the render target setup with webgl_reversed_depth_buffer.

But before merging this, we should find out why Firefox+Windows is the only combination that needs a higher precision. All others don't and this change makes the implementation slower for all these devices.

@Mugen87 Mugen87 marked this pull request as draft March 15, 2026 19:48
@PoseidonEnergy PoseidonEnergy changed the title Fix WebGPU reversed z-buffer example WebGPU: Use depth32float instead of depth24plus Mar 15, 2026
@PoseidonEnergy PoseidonEnergy changed the title WebGPU: Use depth32float instead of depth24plus WebGPU + reversedDepthBuffer: Use depth32float instead of depth24plus Mar 15, 2026
@PoseidonEnergy PoseidonEnergy changed the title WebGPU + reversedDepthBuffer: Use depth32float instead of depth24plus WebGPU reversedDepthBuffer: Use depth32float instead of depth24plus Mar 15, 2026
@github-actions

github-actions Bot commented Mar 15, 2026

Copy link
Copy Markdown

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 359.97
85.54
359.97
85.54
+0 B
+0 B
WebGPU 631.1
175.11
631.34
175.16
+244 B
+45 B
WebGPU Nodes 629.21
174.83
629.46
174.87
+244 B
+45 B

🌳 Bundle size after tree-shaking

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

Before After Diff
WebGL 492.17
120.12
492.17
120.12
+0 B
+0 B
WebGPU 703.53
189.96
703.77
190
+244 B
+49 B
WebGPU Nodes 652.75
177.35
653
177.4
+244 B
+50 B

@PoseidonEnergy

PoseidonEnergy commented Mar 15, 2026

Copy link
Copy Markdown
Contributor Author

I understand the PR aligns the render target setup with webgl_reversed_depth_buffer.

But before merging this, we should find out why Firefox+Windows is the only combination that needs a higher precision. All others don't and this change makes the implementation slower for all these devices.

@Mugen87 I think depth24plus is implementation-flexible in WebGPU. It may be backed by either 24-bit depth or depth32float depending on the implementation, which is why in Chrome it works well but Firefox still had z-fighting.

The following is a quote from https://www.w3.org/TR/webgpu which shows it is implementation-specific:

The depth component of the "depth24plus" and "depth24plus-stencil8" formats may be implemented as either a 24-bit depth value or a "depth32float" value.

I just reverted the changes to the reverse-Z example and instead explicitly upped the depth precision when reversedDepthBuffer is true. This appeared to have fixed the example, without having to make changes to the example.

@PoseidonEnergy PoseidonEnergy marked this pull request as ready for review March 15, 2026 21:58
Comment thread src/renderers/webgpu/utils/WebGPUTextureUtils.js
Comment thread src/nodes/display/PassNode.js Outdated
Comment thread src/renderers/webgpu/utils/WebGPUUtils.js
@PoseidonEnergy

PoseidonEnergy commented Mar 16, 2026

Copy link
Copy Markdown
Contributor Author

@Mugen87 I made some changes according to your suggestions, let me know how they look.

@Mugen87 Mugen87 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good to me! I think we can give this a try.

@sunag Are you okay with these changes?

@Mugen87 Mugen87 added this to the r184 milestone Mar 16, 2026
@sunag

sunag commented Mar 16, 2026

Copy link
Copy Markdown
Collaborator

@sunag Are you okay with these changes?

Wouldn't it be better if we had a depthType that could override it when assigned?
Like WebGPURenderer( { depthType: FloatType } ). I think it could cover more use cases.

@Mugen87

Mugen87 commented Mar 16, 2026

Copy link
Copy Markdown
Collaborator

I think it's better when the user does not have to worry about the depth texture type. This is rather technical and most users won't get it right. Enabling reverse depth buffer should make the feature work everywhere.

#33184 (comment) makes me consider to use THREE.FloatType by default for depth textures. The fact that implementations might interpret depth24plus differently is worrying in context of other use cases as well. Varying depth precision was already in earlier days of three.js a typical source of confusion.

Normally a 24 bit depth buffer should be sufficient but there are use cases (like reverse depth buffer) where it obviously doesn't. Also many devices already interpret depth24plus as 32 bit so there should be no performance regression. Mobile is something to look after though.

For now, I would use FloatType just in context of reverse depth buffer and see how it goes.

@sunag

sunag commented Mar 16, 2026

Copy link
Copy Markdown
Collaborator

Using 32-bit as the default and fallback to 24-bit sounds great if we can do it safely.

My concern would be, as you yourself said, that a 24-bit depth buffer might not be sufficient for all use cases. Maybe someone would want to use this without enabling reverse depth; I thought the idea would be similar to outputBufferType in that sense.

If you are confident, let’s move forward, we can change this later if necessary.

@Mugen87 Mugen87 merged commit 9b054a2 into mrdoob:dev Mar 16, 2026
10 checks passed
@Mugen87

Mugen87 commented Mar 16, 2026

Copy link
Copy Markdown
Collaborator

@PoseidonEnergy Thank you for working on this! #33184 (comment) is an important insight!

@sunag sunag changed the title WebGPU reversedDepthBuffer: Use depth32float instead of depth24plus WebGPURenderer: Use depth32float instead of depth24plus when using reversedDepthBuffer Mar 16, 2026
@Makio64

Makio64 commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

@Mugen87 @PoseidonEnergy @sunag I would really prefer to keep low precision default whenever possible. 8bit is a lot of bandwidth if not needed.

Production code as to deal with low end device all the time, also Threejs did it in past with halfFloat everywhere for mobile and it was a very nice approach.

@Mugen87

Mugen87 commented Mar 17, 2026

Copy link
Copy Markdown
Collaborator

Given that reverse depth buffer requires 32 bit depth, there is no way around I'm afraid.

Devices that worked so far already used 32 bit depth. The others are now force so the feature is actually functional.

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.

Reversed depth buffer / Z-buffer not working in Firefox

4 participants