Skip to content

WebGPURenderer: Fix shadow comparison on Adreno GPUs.#32547

Closed
mrdoob wants to merge 2 commits into
devfrom
webgpu-shadows-fix
Closed

WebGPURenderer: Fix shadow comparison on Adreno GPUs.#32547
mrdoob wants to merge 2 commits into
devfrom
webgpu-shadows-fix

Conversation

@mrdoob

@mrdoob mrdoob commented Dec 13, 2025

Copy link
Copy Markdown
Owner

Seems like the WebGPU backend shadows code produces artifacts on some Samsung devices:

https://x.com/alekswritescode/status/1999543059697057811
https://x.com/Andersonmancini/status/1999549976733528494
https://x.com/nctisz/status/1999480697497833669
https://x.com/ErikSombroek/status/1999445729698554099
https://x.com/the_best_codes/status/1999526930538787278

I currently do not have any of those devices at hand, but I thought I could share the issue with Claude to see if it could figure it out.

Here's what Claude found and the proposed solution 🤞

Description

Fixes shadow rendering issues on Android devices with Adreno GPUs (Samsung Galaxy S23/S25/Fold7, Xiaomi 10T Pro, etc.) when using WebGPURenderer.

Problem

The depth24plus format in WebGPU can be backed by either depth24unorm or depth32float, with different clamping behavior for textureSampleCompare:

  • depth24unorm: reference values are auto-clamped to [0,1]
  • depth32float: reference values are NOT clamped

On Adreno GPUs, depth24plus appears to use depth32float. When shadow coordinate Z goes slightly out of range (due to bias or precision), the comparison produces incorrect results.

See: gpuweb/gpuweb#4653

Solution

Clamp the shadow comparison reference value to [0,1] using .saturate() for consistent behavior across all GPU implementations.

@mrdoob mrdoob added this to the r183 milestone Dec 13, 2025
@github-actions

github-actions Bot commented Dec 13, 2025

Copy link
Copy Markdown

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 355.12
84.44
355.12
84.44
+0 B
+0 B
WebGPU 616.54
171.12
616.57
171.13
+34 B
+9 B
WebGPU Nodes 615.14
170.85
615.18
170.86
+34 B
+9 B

🌳 Bundle size after tree-shaking

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

Before After Diff
WebGL 487.3
119.32
487.3
119.32
+0 B
+0 B
WebGPU 687.29
186.66
687.32
186.67
+34 B
+7 B
WebGPU Nodes 637.13
173.88
637.17
173.88
+34 B
+7 B

@mrdoob mrdoob requested a review from sunag December 13, 2025 11:56
@sunag

sunag commented Dec 13, 2025

Copy link
Copy Markdown
Collaborator

@sunag

sunag commented Dec 13, 2025

Copy link
Copy Markdown
Collaborator

I get a phone to do the tests, I just made sure to check if it wasn't related to the cache of github.

The problem is still occurring.

image

@Mugen87

Mugen87 commented Dec 13, 2025

Copy link
Copy Markdown
Collaborator

So the artifacts do no appear when using WebGL 2 backend, right?

@sunag

sunag commented Dec 13, 2025

Copy link
Copy Markdown
Collaborator

So the artifacts do no appear when using WebGL 2 backend, right?

Yes!

@sunag

sunag commented Dec 13, 2025

Copy link
Copy Markdown
Collaborator

it seems that is related with 'depthTexture.compareFunction = LessCompare' I got it working here., but Chrome debugging is crashing for me; I just need to double-check it.

@sunag

sunag commented Dec 13, 2025

Copy link
Copy Markdown
Collaborator

using 'step()' instead of 'textureSampleCompare()' seems to be the way to go.

image

@mrdoob

mrdoob commented Dec 14, 2025

Copy link
Copy Markdown
Owner Author

Good try Claude, good try 😁

@mrdoob mrdoob closed this Dec 14, 2025
@mrdoob mrdoob deleted the webgpu-shadows-fix branch December 14, 2025 02:51
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