Skip to content

Commit b103c0e

Browse files
authored
NodeMaterial: Add maskShadowNode (#32598)
1 parent ab0ae39 commit b103c0e

4 files changed

Lines changed: 34 additions & 34 deletions

File tree

examples/webgpu_shadowmap.html

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,22 +107,7 @@
107107

108108
const discardNode = hash( vertexIndex ).greaterThan( 0.5 );
109109

110-
materialCustomShadow.colorNode = Fn( () => {
111-
112-
discardNode.discard();
113-
114-
return materialColor;
115-
116-
} )();
117-
118-
119-
materialCustomShadow.castShadowNode = Fn( () => {
120-
121-
discardNode.discard();
122-
123-
return materialColor;
124-
125-
} )();
110+
materialCustomShadow.maskNode = discardNode;
126111

127112
torusKnot = new THREE.Mesh( geometry, materialCustomShadow );
128113
torusKnot.scale.multiplyScalar( 1 / 18 );

examples/webgpu_tsl_angular_slicing.html

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,16 @@
113113
const sliceArc = uniform( 1.25 );
114114
const sliceColor = uniform( color( '#b62f58' ) );
115115

116-
// output
116+
// mask
117117

118-
slicedMaterial.outputNode = Fn( () => {
118+
const mask = inAngle( positionLocal.xy, sliceStart, sliceArc ).not();
119+
120+
slicedMaterial.maskNode = mask;
121+
//slicedMaterial.maskShadowNode = mask; // optional: custom mask shadows
119122

120-
// discard
123+
// output
121124

122-
inAngle( positionLocal.xy, sliceStart, sliceArc ).discard();
125+
slicedMaterial.outputNode = Fn( () => {
123126

124127
// backface color
125128

@@ -134,18 +137,6 @@
134137

135138
} )();
136139

137-
// shadow
138-
139-
slicedMaterial.castShadowNode = Fn( () => {
140-
141-
// discard
142-
143-
inAngle( positionLocal.xy, sliceStart, sliceArc ).discard();
144-
145-
return vec4( 0, 0, 0, 1 );
146-
147-
} )();
148-
149140
// model
150141

151142
const dracoLoader = new DRACOLoader();

src/materials/nodes/NodeMaterial.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,14 @@ class NodeMaterial extends Material {
240240
*/
241241
this.maskNode = null;
242242

243+
/**
244+
* This node can be used to implement a shadow mask for the material.
245+
*
246+
* @type {?Node<bool>}
247+
* @default null
248+
*/
249+
this.maskShadowNode = null;
250+
243251
/**
244252
* The local vertex positions are computed based on multiple factors like the
245253
* attribute data, morphing or skinning. This node property allows to overwrite
@@ -1339,6 +1347,7 @@ class NodeMaterial extends Material {
13391347
this.backdropAlphaNode = source.backdropAlphaNode;
13401348
this.alphaTestNode = source.alphaTestNode;
13411349
this.maskNode = source.maskNode;
1350+
this.maskShadowNode = source.maskShadowNode;
13421351

13431352
this.positionNode = source.positionNode;
13441353
this.geometryNode = source.geometryNode;

src/renderers/common/Renderer.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { Vector4 } from '../../math/Vector4.js';
3232
import { RenderTarget } from '../../core/RenderTarget.js';
3333
import { DoubleSide, BackSide, FrontSide, SRGBColorSpace, NoToneMapping, LinearFilter, HalfFloatType, RGBAFormat, PCFShadowMap } from '../../constants.js';
3434

35-
import { float, vec3, vec4 } from '../../nodes/tsl/TSLCore.js';
35+
import { float, vec3, vec4, Fn } from '../../nodes/tsl/TSLCore.js';
3636
import { reference } from '../../nodes/accessors/ReferenceNode.js';
3737
import { highpModelNormalViewMatrix, highpModelViewMatrix } from '../../nodes/accessors/ModelNode.js';
3838
import { context } from '../../nodes/core/ContextNode.js';
@@ -3035,12 +3035,13 @@ class Renderer {
30353035
const hasMap = material.map !== null;
30363036
const hasColorNode = material.colorNode && material.colorNode.isNode;
30373037
const hasCastShadowNode = material.castShadowNode && material.castShadowNode.isNode;
3038+
const hasMaskNode = ( material.maskShadowNode && material.maskShadowNode.isNode ) || ( material.maskNode && material.maskNode.isNode );
30383039

30393040
let positionNode = null;
30403041
let colorNode = null;
30413042
let depthNode = null;
30423043

3043-
if ( hasMap || hasColorNode || hasCastShadowNode ) {
3044+
if ( hasMap || hasColorNode || hasCastShadowNode || hasMaskNode ) {
30443045

30453046
let shadowRGB;
30463047
let shadowAlpha;
@@ -3071,6 +3072,20 @@ class Renderer {
30713072

30723073
colorNode = vec4( shadowRGB, shadowAlpha );
30733074

3075+
if ( hasMaskNode ) {
3076+
3077+
const maskNode = material.maskShadowNode || material.maskNode;
3078+
3079+
colorNode = Fn( ( [ color ] ) => {
3080+
3081+
maskNode.not().discard();
3082+
3083+
return color;
3084+
3085+
} )( colorNode );
3086+
3087+
}
3088+
30743089
}
30753090

30763091
if ( material.depthNode && material.depthNode.isNode ) {

0 commit comments

Comments
 (0)