WebGPU shadow tests and findings

I have done some tests with shadows in the WebGPU renderer. I know that the WebGPU renderer is still WIP, but wanted to just validate these findings here. I created a codePen for these tests:

https://codepen.io/jarseal/pen/yyyGKPx?editors=1010

Here are some of my findings:

1. Point light shadows break down when using VSMShadowMap

Error (first error message): Error while parsing WGSL: :281:15 error: no matching call to 'textureSampleCompare(texture_2d<f32>, sampler, vec2<f32>, f32)'

Settings to reproduce in the pen:

const isWebGPU = true;
const forceWebGL = false;
const rendererShadowMapType = 'VSMShadowMap';

And it also breaks down with “forceWebGL = true” but gives a different error (first error message): THREE.WebGLProgram: Shader Error 0 - VALIDATE_STATUS false

Settings to reproduce in the pen:

const isWebGPU = true;
const forceWebGL = true;
const rendererShadowMapType = 'VSMShadowMap';

This works fine in the WebGL renderer.

2. Turning on/off “castShadow” and map size dynamically for lights (point, spot, and directional) does not work in WebGPU (also for “forceWebGL = true”)

Settings to reproduce in the pen:

const isWebGPU = true;
const forceWebGL = false;

and

const isWebGPU = true;
const forceWebGL = true;

This works fine in the WebGL renderer.

3. Documentation does not match actual behavior

This is not really a bug, but found out that the “LightShadow” does take into account the “radius” value even if the renderer shadow map type is “PCFSoftShadowMap” for PointLights in WebGPU. In the documentation there is a mention that the “radius” does not have any affect if “PCFSoftShadowMap” is used.

Documentation for LightShadow radius: three.js docs

If WebGLRenderer.shadowMap.type is set to PCFSoftShadowMap, radius has no effect and it is recommended to increase softness by decreasing mapSize instead.

Settings to reproduce in the pen:

const isWebGPU = true;
const forceWebGL = false;
const rendererShadowMapType = 'PCFSoftShadowMap';

and

const isWebGPU = true;
const forceWebGL = true;
const rendererShadowMapType = 'PCFSoftShadowMap';

So, just wanted to validate my findings here. If these are actual bugs/issues and not just some misconfigurations on my part I can make issues out of these in GitHub. I really love the WebGPU renderer. Cheers!

The first issue should be fixed with the below PR. In general, point lights are not compatible with VSM so WebGPURenderer must ensure the default shadow filter for point lights is used, even when the shadow map type is VSMShadowMap.

2 Likes

I can’t reproduce this in your code. PCFSoftShadowMap does definitely not use radius in WebGLRenderer and WebGPURenderer for directional and spot lights. For point lights though, PCFShadowMap, PCFSoftShadowMap and VSMShadowMap all use the same implementation and make use of the shadow radius.

My point was that in the documentation it says that radius doesn’t have any effect if PCFSoftShadowMap is used. This is not the case for PointLight so therefore the documentation is wrong, isn’t it (not a big deal, just pointing it out)?

Thanks for fixing the PointLight/VSMShadowMap issue so quickly.

1 Like

Ah okay, that is true. The situation of shadow-casting point lights is a bit special so maybe we have to document this topic differently.

1 Like

Regarding #2:

I have a program with a couple of different camera locations in which I change the shadow mapsize for each view. The mapsize for the cockpit view is 8192x8192 and the mapsize for the external view is 2048x2048. I do not get any error messages and it seems to be working (I can test if you like by reducing the mapsize for the external view to some really small value). I also change the camera_far value.

Here are the commands I use:

sunLight.shadow.mapSize.set(2048,2048);
sunLight.shadow.camera.far = sky_.SunDst+sky_.ShdDst+sky_.ShdBox;
sunLight.shadow.camera.updateProjectionMatrix();

I am not sure how many of the basic values you can change dynamically using this method.

1 Like

This will be fixed with the next release as well.

3 Likes