Addons: WebGPU CSM shadows - using shadowNode
Related issue: #29295
CSM implemented using shadowNode.
This uses dummy light objects to use the existing mechanism for updating the cascades shadow cameras, without injecting additional lights into the scene.
The original csm.lightDirection is replaced by the DirectionalLights direction and shadow parameters are inherited from the lights shadow object.
This issue where switching between fade and non-fade modes requires triggering a rebuild by disabling and reenabling shadows remains.
📦 Bundle size
Full ESM build, minified and gzipped.
| Before | After | Diff | |
|---|---|---|---|
| WebGL | 691.57 171.41 |
691.57 171.41 |
+0 B +0 B |
| WebGPU | 818.89 220.86 |
818.94 220.87 |
+54 B +12 B |
| WebGPU Nodes | 818.4 220.72 |
818.45 220.73 |
+54 B +12 B |
🌳 Bundle size after tree-shaking
Minimal build including a renderer, camera, empty scene, and dependencies.
| Before | After | Diff | |
|---|---|---|---|
| WebGL | 463.72 112.16 |
463.72 112.16 |
+0 B +0 B |
| WebGPU | 539.75 145.78 |
539.8 145.81 |
+54 B +21 B |
| WebGPU Nodes | 495.74 135.6 |
495.8 135.63 |
+54 B +23 B |
This issue where switching between fade and non-fade modes requires triggering a rebuild by disabling and reenabling shadows remains.
It seems toggling the fade option in webgl_shadowmap_csm has a different effect than in webgpu_shadowmap_csm where I can barely see any change. Is the mentioned rebuild missing?
webgpu_shadowmap_csm does not run in Firefox/WebGL. I just see the blue/gray background. The following WebGL warnings are logged:
WebGL warning: drawElementsInstanced: Buffer for uniform block is smaller than UNIFORM_BLOCK_DATA_SIZE. After reporting 32, no further warnings will be reported for this WebGL context.
I get the same errors on Chrome WebGL. Appears to be an issue with vec2[4] cascades array. Hardcoding a vec2() rather than cascades.element( n ) in the shader removes the error and is equivalent to how the original PR worked.
Looking at the issue at the moment.
The WebGL version works now 🎉 .
During testing, I have noticed that when using a WebGL backend and an orthographic camera, the shadows start with an offset:
WebGPURenderer(WebGL):
WebGLRenderer:
I have fixed the issue with the WebGL backend and orthographic cameras via https://github.com/mrdoob/three.js/pull/29610/commits/b441f99e1897937af2ca7d9c3cd0c7d07f401412.
Fading is still broken though. Not sure where the root cause is yet...
The far shadow distances also do not match with the original.
What is the exact issue with fading? Apart from requiring toggling shadow on and off to get the material to rebuild.
When you turn fade one, try to move the camera away. Below are two screenshot from webgl_shadowmap_csm.
Without fading:
With fading:
In the webgpu_shadowmap_csm, the fading is missing. Even toggling shadows does not seem to have an effect.
Fixed up the fading now
I've revisited the implementation several days now but I can't explain the difference of the shadow frustums so far. I have the feeling the frustums are not correctly transformed for some reasons.
I think the parameters of shadow camera (I mean csm.lights[i].shadow.camera.xxx) should not copy from the main light directly, especially .far, it has a siginificant affection to precision, we should keep a narrowest box of each frustum. But unfortunatelly, I don't know the formula about it.
In my scene, I can't get a proper value for '.far', If it's too small, I can get better effect near the camera, but the shadow disappears at the farthest edge of each frustum. If it's too large, the shadow is gone.