Skip to content

Commit

Permalink
WebGPURenderer: Shadow fixes (mrdoob#29991)
Browse files Browse the repository at this point in the history
* shadow revision

* cleanup

* cleanup

* rev
  • Loading branch information
sunag authored Nov 29, 2024
1 parent e2e04d3 commit f91fbc3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 23 deletions.
4 changes: 2 additions & 2 deletions src/nodes/lighting/PointShadowNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ const pointShadowFilter = /*@__PURE__*/ Fn( ( { filterFn, depthTexture, shadowCo
const lightToPosition = shadowCoord.xyz.toVar();
const lightToPositionLength = lightToPosition.length();

const cameraNearLocal = uniform( 'float' ).onRenderUpdate( () => shadow.camera.near );
const cameraFarLocal = uniform( 'float' ).onRenderUpdate( () => shadow.camera.far );
const cameraNearLocal = uniform( 'float' ).setGroup( renderGroup ).onRenderUpdate( () => shadow.camera.near );
const cameraFarLocal = uniform( 'float' ).setGroup( renderGroup ).onRenderUpdate( () => shadow.camera.far );
const bias = reference( 'bias', 'float', shadow ).setGroup( renderGroup );
const mapSize = uniform( shadow.mapSize ).setGroup( renderGroup );

Expand Down
46 changes: 31 additions & 15 deletions src/nodes/lighting/ShadowNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ import NodeMaterial from '../../materials/nodes/NodeMaterial.js';
import QuadMesh from '../../renderers/common/QuadMesh.js';
import { Loop } from '../utils/LoopNode.js';
import { screenCoordinate } from '../display/ScreenNode.js';
import { HalfFloatType, LessCompare, RGFormat, VSMShadowMap, WebGPUCoordinateSystem } from '../../constants.js';
import { HalfFloatType, LessCompare, NoBlending, RGFormat, VSMShadowMap, WebGPUCoordinateSystem } from '../../constants.js';
import { renderGroup } from '../core/UniformGroupNode.js';
import { viewZToLogarithmicDepth } from '../display/ViewportDepthNode.js';
import { objectPosition } from '../accessors/Object3DNode.js';
import { lightShadowMatrix } from '../accessors/Lights.js';

const shadowMaterialLib = /*@__PURE__*/ new WeakMap();
const shadowWorldPosition = /*@__PURE__*/ vec3().toVar( 'shadowWorldPosition' );

const linearDistance = /*@__PURE__*/ Fn( ( [ position, cameraNear, cameraFar ] ) => {
Expand All @@ -43,6 +44,29 @@ const linearShadowDistance = ( light ) => {

};

const getShadowMaterial = ( light ) => {

let material = shadowMaterialLib.get( light );

if ( material === undefined ) {

const depthNode = light.isPointLight ? linearShadowDistance( light ) : null;

material = new NodeMaterial();
material.colorNode = vec4( 0, 0, 0, 1 );
material.depthNode = depthNode;
material.isShadowNodeMaterial = true; // Use to avoid other overrideMaterial override material.colorNode unintentionally when using material.shadowNode
material.blending = NoBlending;
material.name = 'ShadowMaterial';

shadowMaterialLib.set( light, material );

}

return material;

};

export const BasicShadowFilter = /*@__PURE__*/ Fn( ( { depthTexture, shadowCoord } ) => {

return texture( depthTexture, shadowCoord.xy ).compare( shadowCoord.z );
Expand Down Expand Up @@ -224,7 +248,6 @@ const _shadowFilterLib = [ BasicShadowFilter, PCFShadowFilter, PCFSoftShadowFilt

//

let _overrideMaterial = null;
const _quadMesh = /*@__PURE__*/ new QuadMesh();

class ShadowNode extends Node {
Expand Down Expand Up @@ -332,18 +355,6 @@ class ShadowNode extends Node {

const shadowMapType = renderer.shadowMap.type;

if ( _overrideMaterial === null ) {

const depthNode = light.isPointLight ? linearShadowDistance( light ) : null;

_overrideMaterial = new NodeMaterial();
_overrideMaterial.fragmentNode = vec4( 0, 0, 0, 1 );
_overrideMaterial.depthNode = depthNode;
_overrideMaterial.isShadowNodeMaterial = true; // Use to avoid other overrideMaterial override material.fragmentNode unintentionally when using material.shadowNode
_overrideMaterial.name = 'ShadowMaterial';

}

const depthTexture = new DepthTexture( shadow.mapSize.width, shadow.mapSize.height );
depthTexture.compareFunction = LessCompare;

Expand Down Expand Up @@ -467,12 +478,15 @@ class ShadowNode extends Node {

const currentOverrideMaterial = scene.overrideMaterial;

scene.overrideMaterial = _overrideMaterial;
scene.overrideMaterial = getShadowMaterial( light );

shadow.camera.layers.mask = camera.layers.mask;

const currentRenderTarget = renderer.getRenderTarget();
const currentRenderObjectFunction = renderer.getRenderObjectFunction();
const currentMRT = renderer.getMRT();

renderer.setMRT( null );

renderer.setRenderObjectFunction( ( object, ...params ) => {

Expand Down Expand Up @@ -500,6 +514,8 @@ class ShadowNode extends Node {

renderer.setRenderTarget( currentRenderTarget );

renderer.setMRT( currentMRT );

scene.overrideMaterial = currentOverrideMaterial;

}
Expand Down
14 changes: 8 additions & 6 deletions src/renderers/common/Renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1633,7 +1633,7 @@ class Renderer {
renderObject( object, scene, camera, geometry, material, group, lightsNode, clippingContext = null, passId = null ) {

let overridePositionNode;
let overrideFragmentNode;
let overrideColorNode;
let overrideDepthNode;

//
Expand All @@ -1653,6 +1653,9 @@ class Renderer {

}

overrideMaterial.alphaTest = material.alphaTest;
overrideMaterial.alphaMap = material.alphaMap;

if ( overrideMaterial.isShadowNodeMaterial ) {

overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide;
Expand All @@ -1664,11 +1667,10 @@ class Renderer {

}


if ( material.castShadowNode && material.castShadowNode.isNode ) {

overrideFragmentNode = overrideMaterial.fragmentNode;
overrideMaterial.fragmentNode = material.castShadowNode;
overrideColorNode = overrideMaterial.colorNode;
overrideMaterial.colorNode = material.castShadowNode;

}

Expand Down Expand Up @@ -1710,9 +1712,9 @@ class Renderer {

}

if ( overrideFragmentNode !== undefined ) {
if ( overrideColorNode !== undefined ) {

scene.overrideMaterial.fragmentNode = overrideFragmentNode;
scene.overrideMaterial.colorNode = overrideColorNode;

}

Expand Down

0 comments on commit f91fbc3

Please sign in to comment.