@@ -7,11 +7,12 @@ import { renderGroup } from '../core/UniformGroupNode.js';
77import { Matrix4 } from '../../math/Matrix4.js' ;
88import { Vector3 } from '../../math/Vector3.js' ;
99import { Color } from '../../math/Color.js' ;
10- import { BasicShadowMap , LessCompare , WebGPUCoordinateSystem } from '../../constants.js' ;
10+ import { BasicShadowMap , LessEqualCompare , WebGPUCoordinateSystem } from '../../constants.js' ;
1111import { CubeDepthTexture } from '../../textures/CubeDepthTexture.js' ;
1212import { screenCoordinate } from '../display/ScreenNode.js' ;
1313import { interleavedGradientNoise , vogelDiskSample } from '../utils/PostProcessingUtils.js' ;
1414import { abs , normalize , cross } from '../math/MathNode.js' ;
15+ import { viewZToPerspectiveDepth } from '../display/ViewportDepthNode.js' ;
1516
1617const _clearColor = /*@__PURE__ */ new Color ( ) ;
1718const _projScreenMatrix = /*@__PURE__ */ new Matrix4 ( ) ;
@@ -97,23 +98,23 @@ const pointShadowFilter = /*@__PURE__*/ Fn( ( { filterFn, depthTexture, shadowCo
9798
9899 // for point lights, the uniform @vShadowCoord is re-purposed to hold
99100 // the vector from the light to the world-space position of the fragment.
100- const lightToPosition = shadowCoord . xyz . toVar ( ) ;
101- const lightToPositionLength = lightToPosition . length ( ) ;
101+ const shadowPosition = shadowCoord . xyz . toConst ( ) ;
102+ const shadowPositionAbs = shadowPosition . abs ( ) . toConst ( ) ;
103+ const viewZ = shadowPositionAbs . x . max ( shadowPositionAbs . y ) . max ( shadowPositionAbs . z ) ;
102104
103- const cameraNearLocal = uniform ( 'float' ) . setGroup ( renderGroup ) . onRenderUpdate ( ( ) => shadow . camera . near ) ;
104- const cameraFarLocal = uniform ( 'float' ) . setGroup ( renderGroup ) . onRenderUpdate ( ( ) => shadow . camera . far ) ;
105+ const shadowCameraNear = uniform ( 'float' ) . setGroup ( renderGroup ) . onRenderUpdate ( ( ) => shadow . camera . near ) ;
106+ const shadowCameraFar = uniform ( 'float' ) . setGroup ( renderGroup ) . onRenderUpdate ( ( ) => shadow . camera . far ) ;
105107 const bias = reference ( 'bias' , 'float' , shadow ) . setGroup ( renderGroup ) ;
106108
107109 const result = float ( 1.0 ) . toVar ( ) ;
108110
109- If ( lightToPositionLength . sub ( cameraFarLocal ) . lessThanEqual ( 0.0 ) . and ( lightToPositionLength . sub ( cameraNearLocal ) . greaterThanEqual ( 0.0 ) ) , ( ) => {
111+ If ( viewZ . sub ( shadowCameraFar ) . lessThanEqual ( 0.0 ) . and ( viewZ . sub ( shadowCameraNear ) . greaterThanEqual ( 0.0 ) ) , ( ) => {
110112
111- // dp = normalized distance from light to fragment position
112- const dp = lightToPositionLength . sub ( cameraNearLocal ) . div ( cameraFarLocal . sub ( cameraNearLocal ) ) . toVar ( ) ; // need to clamp?
113+ const dp = viewZToPerspectiveDepth ( viewZ . negate ( ) , shadowCameraNear , shadowCameraFar ) ;
113114 dp . addAssign ( bias ) ;
114115
115116 // bd3D = base direction 3D (direction from light to fragment)
116- const bd3D = lightToPosition . normalize ( ) ;
117+ const bd3D = shadowPosition . normalize ( ) ;
117118
118119 // percentage-closer filtering using cube texture sampling
119120 result . assign ( filterFn ( { depthTexture, bd3D, dp, shadow } ) ) ;
@@ -205,7 +206,7 @@ class PointShadowNode extends ShadowNode {
205206
206207 const depthTexture = new CubeDepthTexture ( shadow . mapSize . width ) ;
207208 depthTexture . name = 'PointShadowDepthTexture' ;
208- depthTexture . compareFunction = LessCompare ;
209+ depthTexture . compareFunction = LessEqualCompare ;
209210
210211 const shadowMap = builder . createCubeRenderTarget ( shadow . mapSize . width ) ;
211212 shadowMap . texture . name = 'PointShadowMap' ;
0 commit comments