From 1204dd44979fe2df637f30f0d0b1778dd31c933c Mon Sep 17 00:00:00 2001 From: sunag Date: Sat, 7 Dec 2024 15:03:45 -0300 Subject: [PATCH] Reapply "WebGPURenderer: Shadow fixes (#29991)" This reverts commit 50c6e1413a1d59640ca52932b00356aca151e9da. --- src/nodes/lighting/PointShadowNode.js | 4 +-- src/nodes/lighting/ShadowNode.js | 46 ++++++++++++++++++--------- src/renderers/common/Renderer.js | 14 ++++---- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/nodes/lighting/PointShadowNode.js b/src/nodes/lighting/PointShadowNode.js index c33e688287df13..f2d236ee09e207 100644 --- a/src/nodes/lighting/PointShadowNode.js +++ b/src/nodes/lighting/PointShadowNode.js @@ -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 ); diff --git a/src/nodes/lighting/ShadowNode.js b/src/nodes/lighting/ShadowNode.js index 222120745e2c3f..c7088a29eb0bc4 100644 --- a/src/nodes/lighting/ShadowNode.js +++ b/src/nodes/lighting/ShadowNode.js @@ -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 ] ) => { @@ -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 ); @@ -224,7 +248,6 @@ const _shadowFilterLib = [ BasicShadowFilter, PCFShadowFilter, PCFSoftShadowFilt // -let _overrideMaterial = null; const _quadMesh = /*@__PURE__*/ new QuadMesh(); class ShadowNode extends Node { @@ -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; @@ -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, scene, _camera, geometry, material, group, ...params ) => { @@ -504,6 +518,8 @@ class ShadowNode extends Node { renderer.setRenderTarget( currentRenderTarget ); + renderer.setMRT( currentMRT ); + scene.overrideMaterial = currentOverrideMaterial; } diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index d174fa168398d9..8fe7b09c78912e 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -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; // @@ -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; @@ -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; } @@ -1710,9 +1712,9 @@ class Renderer { } - if ( overrideFragmentNode !== undefined ) { + if ( overrideColorNode !== undefined ) { - scene.overrideMaterial.fragmentNode = overrideFragmentNode; + scene.overrideMaterial.colorNode = overrideColorNode; }