I’m trying to add light.shadow.blurSamples support to PCFShadowMap. I want to use the light.shadow.blurSamples value in a TSL shader, but only as a JS value (for loop unrolling), and not as a value in the built shader.
You can see in this snippet I’m using the input shadow.blurSamples, where shadow is the light.shadow (f.e. SpotLightShadow):
export const PCFShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord, shadow, depthLayer } ) => {
// ... other code ...
const samples = [];
for ( let i = 0, l = shadow.blurSamples; i < l; i ++ ) {
samples.push(
depthCompare( shadowCoord.xy.add( vogelDiskSample( i, shadow.blurSamples, phi ).mul( radiusScaled ) ), shadowCoord.z ),
);
}
return add( ...samples ).mul( 1 / shadow.blurSamples );
} );
Here I try to add a reference(), but that doesn’t work because the node is not connected to anything:
export const PCFShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord, shadow, depthLayer } ) => {
// ... other code here ...
// I hoped this might work (but of course not, it is unused):
const blurSamples = reference( 'blurSamples', 'int', shadow ).setGroup( renderGroup );
const samples = [];
// ... the same ...
} );
If I update a light’s shadow.blurSamples, nothing happens. The TSL shader is built only once, initially.
If I change it to a shader-side loop (which makes the shader much slower), then updating blurSamples works:
export const PCFShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord, shadow, depthLayer } ) => {
// ... other code here ...
const blurSamples = reference( 'blurSamples', 'int', shadow ).setGroup( renderGroup );
let sum = float( 0 ).toVar();
Loop( blurSamples, ( { i } ) => { // too slow! But it updates.
sum.addAssign( depthCompare( shadowCoord.xy.add( vogelDiskSample( i, shadow.blurSamples, phi ).mul( radiusScaled ) ), shadowCoord.z ) );
} );
return sum.mul( float( 1 ).div( float( blurSamples ) ) );
} );
How do we make the TSL shader update?
I tried:
light.shadow.blurSamples = newValue
light.shadow.needsUpdate = true // did not work, nothing happens
The following also does not work, and the rendering freezes:
light.shadow.blurSamples = newValue
light.shadow.dispose() // did not work, rendering freezes.