|
|
@@ -190,23 +190,23 @@ export const VSMShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord,
|
|
|
|
|
|
const hardShadow = step( shadowCoord.z, mean );
|
|
|
|
|
|
- // Early return if fully lit
|
|
|
- If( hardShadow.equal( 1.0 ), () => {
|
|
|
+ const output = float( 1 ).toVar(); // default, fully lit
|
|
|
|
|
|
- return float( 1.0 );
|
|
|
+ If( hardShadow.notEqual( 1.0 ), () => {
|
|
|
|
|
|
- } );
|
|
|
+ // Distance from mean
|
|
|
+ const d = shadowCoord.z.sub( mean );
|
|
|
|
|
|
- // Distance from mean
|
|
|
- const d = shadowCoord.z.sub( mean );
|
|
|
+ // Chebyshev's inequality for upper bound on probability
|
|
|
+ let p_max = variance.div( variance.add( d.mul( d ) ) );
|
|
|
|
|
|
- // Chebyshev's inequality for upper bound on probability
|
|
|
- let p_max = variance.div( variance.add( d.mul( d ) ) );
|
|
|
+ // Reduce light bleeding by remapping [amount, 1] to [0, 1]
|
|
|
+ p_max = clamp( sub( p_max, 0.3 ).div( 0.65 ) );
|
|
|
|
|
|
- // Reduce light bleeding by remapping [amount, 1] to [0, 1]
|
|
|
- p_max = clamp( sub( p_max, 0.3 ).div( 0.65 ) );
|
|
|
+ output.assign( max( hardShadow, p_max ) );
|
|
|
|
|
|
- return max( hardShadow, p_max );
|
|
|
+ } );
|
|
|
+ return output;
|
|
|
|
|
|
} );
|
|
|
|