|
@@ -7,11 +7,12 @@ import { renderGroup } from '../core/UniformGroupNode.js';
|
|
|
import { Matrix4 } from '../../math/Matrix4.js';
|
|
import { Matrix4 } from '../../math/Matrix4.js';
|
|
|
import { Vector3 } from '../../math/Vector3.js';
|
|
import { Vector3 } from '../../math/Vector3.js';
|
|
|
import { Color } from '../../math/Color.js';
|
|
import { Color } from '../../math/Color.js';
|
|
|
-import { BasicShadowMap, LessCompare, WebGPUCoordinateSystem } from '../../constants.js';
|
|
|
|
|
|
|
+import { BasicShadowMap, LessEqualCompare, WebGPUCoordinateSystem } from '../../constants.js';
|
|
|
import { CubeDepthTexture } from '../../textures/CubeDepthTexture.js';
|
|
import { CubeDepthTexture } from '../../textures/CubeDepthTexture.js';
|
|
|
import { screenCoordinate } from '../display/ScreenNode.js';
|
|
import { screenCoordinate } from '../display/ScreenNode.js';
|
|
|
import { interleavedGradientNoise, vogelDiskSample } from '../utils/PostProcessingUtils.js';
|
|
import { interleavedGradientNoise, vogelDiskSample } from '../utils/PostProcessingUtils.js';
|
|
|
import { abs, normalize, cross } from '../math/MathNode.js';
|
|
import { abs, normalize, cross } from '../math/MathNode.js';
|
|
|
|
|
+import { viewZToPerspectiveDepth } from '../display/ViewportDepthNode.js';
|
|
|
|
|
|
|
|
const _clearColor = /*@__PURE__*/ new Color();
|
|
const _clearColor = /*@__PURE__*/ new Color();
|
|
|
const _projScreenMatrix = /*@__PURE__*/ new Matrix4();
|
|
const _projScreenMatrix = /*@__PURE__*/ new Matrix4();
|
|
@@ -97,23 +98,23 @@ const pointShadowFilter = /*@__PURE__*/ Fn( ( { filterFn, depthTexture, shadowCo
|
|
|
|
|
|
|
|
// for point lights, the uniform @vShadowCoord is re-purposed to hold
|
|
// for point lights, the uniform @vShadowCoord is re-purposed to hold
|
|
|
// the vector from the light to the world-space position of the fragment.
|
|
// the vector from the light to the world-space position of the fragment.
|
|
|
- const lightToPosition = shadowCoord.xyz.toVar();
|
|
|
|
|
- const lightToPositionLength = lightToPosition.length();
|
|
|
|
|
|
|
+ const shadowPosition = shadowCoord.xyz.toConst();
|
|
|
|
|
+ const shadowPositionAbs = shadowPosition.abs().toConst();
|
|
|
|
|
+ const viewZ = shadowPositionAbs.x.max( shadowPositionAbs.y ).max( shadowPositionAbs.z );
|
|
|
|
|
|
|
|
- const cameraNearLocal = uniform( 'float' ).setGroup( renderGroup ).onRenderUpdate( () => shadow.camera.near );
|
|
|
|
|
- const cameraFarLocal = uniform( 'float' ).setGroup( renderGroup ).onRenderUpdate( () => shadow.camera.far );
|
|
|
|
|
|
|
+ const shadowCameraNear = uniform( 'float' ).setGroup( renderGroup ).onRenderUpdate( () => shadow.camera.near );
|
|
|
|
|
+ const shadowCameraFar = uniform( 'float' ).setGroup( renderGroup ).onRenderUpdate( () => shadow.camera.far );
|
|
|
const bias = reference( 'bias', 'float', shadow ).setGroup( renderGroup );
|
|
const bias = reference( 'bias', 'float', shadow ).setGroup( renderGroup );
|
|
|
|
|
|
|
|
const result = float( 1.0 ).toVar();
|
|
const result = float( 1.0 ).toVar();
|
|
|
|
|
|
|
|
- If( lightToPositionLength.sub( cameraFarLocal ).lessThanEqual( 0.0 ).and( lightToPositionLength.sub( cameraNearLocal ).greaterThanEqual( 0.0 ) ), () => {
|
|
|
|
|
|
|
+ If( viewZ.sub( shadowCameraFar ).lessThanEqual( 0.0 ).and( viewZ.sub( shadowCameraNear ).greaterThanEqual( 0.0 ) ), () => {
|
|
|
|
|
|
|
|
- // dp = normalized distance from light to fragment position
|
|
|
|
|
- const dp = lightToPositionLength.sub( cameraNearLocal ).div( cameraFarLocal.sub( cameraNearLocal ) ).toVar(); // need to clamp?
|
|
|
|
|
|
|
+ const dp = viewZToPerspectiveDepth( viewZ.negate(), shadowCameraNear, shadowCameraFar );
|
|
|
dp.addAssign( bias );
|
|
dp.addAssign( bias );
|
|
|
|
|
|
|
|
// bd3D = base direction 3D (direction from light to fragment)
|
|
// bd3D = base direction 3D (direction from light to fragment)
|
|
|
- const bd3D = lightToPosition.normalize();
|
|
|
|
|
|
|
+ const bd3D = shadowPosition.normalize();
|
|
|
|
|
|
|
|
// percentage-closer filtering using cube texture sampling
|
|
// percentage-closer filtering using cube texture sampling
|
|
|
result.assign( filterFn( { depthTexture, bd3D, dp, shadow } ) );
|
|
result.assign( filterFn( { depthTexture, bd3D, dp, shadow } ) );
|
|
@@ -205,7 +206,7 @@ class PointShadowNode extends ShadowNode {
|
|
|
|
|
|
|
|
const depthTexture = new CubeDepthTexture( shadow.mapSize.width );
|
|
const depthTexture = new CubeDepthTexture( shadow.mapSize.width );
|
|
|
depthTexture.name = 'PointShadowDepthTexture';
|
|
depthTexture.name = 'PointShadowDepthTexture';
|
|
|
- depthTexture.compareFunction = LessCompare;
|
|
|
|
|
|
|
+ depthTexture.compareFunction = LessEqualCompare;
|
|
|
|
|
|
|
|
const shadowMap = builder.createCubeRenderTarget( shadow.mapSize.width );
|
|
const shadowMap = builder.createCubeRenderTarget( shadow.mapSize.width );
|
|
|
shadowMap.texture.name = 'PointShadowMap';
|
|
shadowMap.texture.name = 'PointShadowMap';
|