Bläddra i källkod

WebGPURenderer: Fix 'receiveShadow' and introduce `shadowPositionNode` (#28146)

* fix receive shadow and introduce shadowPositionNode

* fix receive only and example

* better fix

* update example

* add color noise to example
Renaud Rohlinger 1 år sedan
förälder
incheckning
34cfc4d11c

+ 8 - 2
examples/jsm/nodes/lighting/AnalyticLightNode.js

@@ -50,6 +50,10 @@ class AnalyticLightNode extends LightingNode {
 
 	setupShadow( builder ) {
 
+		const { object } = builder;
+
+		if ( object.receiveShadow === false ) return;
+
 		let shadowNode = this.shadowNode;
 
 		if ( shadowNode === null ) {
@@ -81,7 +85,9 @@ class AnalyticLightNode extends LightingNode {
 			const bias = reference( 'bias', 'float', shadow );
 			const normalBias = reference( 'normalBias', 'float', shadow );
 
-			let shadowCoord = uniform( shadow.matrix ).mul( positionWorld.add( normalWorld.mul( normalBias ) ) );
+			const position = object.material.shadowPositionNode || positionWorld;
+
+			let shadowCoord = uniform( shadow.matrix ).mul( position.add( normalWorld.mul( normalBias ) ) );
 			shadowCoord = shadowCoord.xyz.div( shadowCoord.w );
 
 			const frustumTest = shadowCoord.x.greaterThanEqual( 0 )
@@ -145,7 +151,7 @@ class AnalyticLightNode extends LightingNode {
 				textureCompare( depthTexture, shadowCoord.xy.add( vec2( 0, dy1 ) ), shadowCoord.z ),
 				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx1, dy1 ) ), shadowCoord.z )
 			).mul( 1 / 17 );
-			*/
+			 */
 			//
 
 			const shadowColor = texture( rtt.texture, shadowCoord );

+ 2 - 0
examples/jsm/nodes/materials/NodeMaterial.js

@@ -57,6 +57,7 @@ class NodeMaterial extends ShaderMaterial {
 
 		this.depthNode = null;
 		this.shadowNode = null;
+		this.shadowPositionNode = null;
 
 		this.outputNode = null;
 
@@ -530,6 +531,7 @@ class NodeMaterial extends ShaderMaterial {
 
 		this.depthNode = source.depthNode;
 		this.shadowNode = source.shadowNode;
+		this.shadowPositionNode = source.shadowPositionNode;
 
 		this.outputNode = source.outputNode;
 

+ 1 - 1
examples/jsm/renderers/common/ClippingContext.js

@@ -101,7 +101,7 @@ class ClippingContext {
 
 		if ( this !== parent && parent.version !== this.parentVersion ) {
 
-			this.globalClippingCount =  material.isShadowNodeMaterial ? 0 : parent.globalClippingCount;
+			this.globalClippingCount = material.isShadowNodeMaterial ? 0 : parent.globalClippingCount;
 			this.localClippingEnabled = parent.localClippingEnabled;
 			this.planes = Array.from( parent.planes );
 			this.parentVersion = parent.version;

BIN
examples/screenshots/webgpu_shadowmap.jpg


+ 2 - 0
examples/webgpu_reflection.html

@@ -131,6 +131,8 @@
 				floorMaterial.colorNode = texture( floorColor, floorUV ).add( reflection );
 
 				const floor = new THREE.Mesh( new THREE.BoxGeometry( 50, .001, 50 ), floorMaterial );
+				floor.receiveShadow = true;
+
 				floor.position.set( 0, 0, 0 );
 				scene.add( floor );
 

+ 19 - 2
examples/webgpu_shadowmap.html

@@ -31,7 +31,7 @@
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 
 			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
-			import { vec4, tslFn, color, vertexIndex, MeshPhongNodeMaterial } from 'three/nodes';
+			import { mx_fractal_noise_vec3, positionWorld, vec4, tslFn, color, vertexIndex, MeshPhongNodeMaterial } from 'three/nodes';
 			let camera, scene, renderer, clock;
 			let dirLight, spotLight;
 			let torusKnot, dirGroup;
@@ -115,6 +115,7 @@
 
 				} )();
 
+
 				materialCustomShadow.shadowNode = tslFn( () => {
 
 					discardNode.discard();
@@ -135,7 +136,6 @@
 				const pillar1 = new THREE.Mesh( cylinderGeometry, material );
 				pillar1.position.set( 8, 3.5, 8 );
 				pillar1.castShadow = true;
-				pillar1.receiveShadow = true;
 
 				const pillar2 = pillar1.clone();
 				pillar2.position.set( 8, 3.5, - 8 );
@@ -156,6 +156,23 @@
 					specular: 0x111111
 				} );
 
+				planeMaterial.shadowPositionNode = tslFn( () => {
+
+					const pos = positionWorld.toVar();
+					pos.xz.addAssign( mx_fractal_noise_vec3( positionWorld.mul( 2 ) ).saturate().xz );
+					return pos;
+
+				} )();
+
+
+				planeMaterial.colorNode = tslFn( () => {
+
+					const pos = positionWorld.toVar();
+					pos.xz.addAssign( mx_fractal_noise_vec3( positionWorld.mul( 2 ) ).saturate().xz );
+					return mx_fractal_noise_vec3( positionWorld.mul( 2 ) ).saturate().zzz.mul( 0.2 ).add( .5 );
+
+				} )();
+
 				const ground = new THREE.Mesh( planeGeometry, planeMaterial );
 				ground.rotation.x = - Math.PI / 2;
 				ground.scale.multiplyScalar( 3 );