浏览代码

TSL: Depth nodes revision (#28720)

* revision depth node

* update examples

* cleanup
sunag 1 年之前
父节点
当前提交
172f0c6642

+ 1 - 1
examples/jsm/nodes/Nodes.js

@@ -121,7 +121,7 @@ export { default as ViewportNode, viewport, viewportCoordinate, viewportResoluti
 export { default as ViewportTextureNode, viewportTexture, viewportMipTexture } from './display/ViewportTextureNode.js';
 export { default as ViewportTextureNode, viewportTexture, viewportMipTexture } from './display/ViewportTextureNode.js';
 export { default as ViewportSharedTextureNode, viewportSharedTexture } from './display/ViewportSharedTextureNode.js';
 export { default as ViewportSharedTextureNode, viewportSharedTexture } from './display/ViewportSharedTextureNode.js';
 export { default as ViewportDepthTextureNode, viewportDepthTexture } from './display/ViewportDepthTextureNode.js';
 export { default as ViewportDepthTextureNode, viewportDepthTexture } from './display/ViewportDepthTextureNode.js';
-export { default as ViewportDepthNode, viewZToOrthographicDepth, orthographicDepthToViewZ, viewZToPerspectiveDepth, perspectiveDepthToViewZ, depth, depthTexture, depthPixel } from './display/ViewportDepthNode.js';
+export { default as ViewportDepthNode, viewZToOrthographicDepth, orthographicDepthToViewZ, viewZToPerspectiveDepth, perspectiveDepthToViewZ, depth, linearDepth, viewportLinearDepth } from './display/ViewportDepthNode.js';
 export { default as GaussianBlurNode, gaussianBlur } from './display/GaussianBlurNode.js';
 export { default as GaussianBlurNode, gaussianBlur } from './display/GaussianBlurNode.js';
 export { default as AfterImageNode, afterImage } from './display/AfterImageNode.js';
 export { default as AfterImageNode, afterImage } from './display/AfterImageNode.js';
 export { default as AnamorphicNode, anamorphic } from './display/AnamorphicNode.js';
 export { default as AnamorphicNode, anamorphic } from './display/AnamorphicNode.js';

+ 4 - 3
examples/jsm/nodes/core/NodeBuilder.js

@@ -60,14 +60,15 @@ const toFloat = ( value ) => {
 
 
 class NodeBuilder {
 class NodeBuilder {
 
 
-	constructor( object, renderer, parser, scene = null, material = null ) {
+	constructor( object, renderer, parser ) {
 
 
 		this.object = object;
 		this.object = object;
-		this.material = material || ( object && object.material ) || null;
+		this.material = ( object && object.material ) || null;
 		this.geometry = ( object && object.geometry ) || null;
 		this.geometry = ( object && object.geometry ) || null;
 		this.renderer = renderer;
 		this.renderer = renderer;
 		this.parser = parser;
 		this.parser = parser;
-		this.scene = scene;
+		this.scene = null;
+		this.camera = null;
 
 
 		this.nodes = [];
 		this.nodes = [];
 		this.updateNodes = [];
 		this.updateNodes = [];

+ 39 - 16
examples/jsm/nodes/display/ViewportDepthNode.js

@@ -21,7 +21,7 @@ class ViewportDepthNode extends Node {
 
 
 		const { scope } = this;
 		const { scope } = this;
 
 
-		if ( scope === ViewportDepthNode.DEPTH_PIXEL ) {
+		if ( scope === ViewportDepthNode.DEPTH ) {
 
 
 			return builder.getFragDepth();
 			return builder.getFragDepth();
 
 
@@ -31,28 +31,52 @@ class ViewportDepthNode extends Node {
 
 
 	}
 	}
 
 
-	setup( /*builder*/ ) {
+	setup( { camera } ) {
 
 
 		const { scope } = this;
 		const { scope } = this;
+		const texture = this.valueNode;
 
 
 		let node = null;
 		let node = null;
 
 
 		if ( scope === ViewportDepthNode.DEPTH ) {
 		if ( scope === ViewportDepthNode.DEPTH ) {
 
 
-			node = viewZToOrthographicDepth( positionView.z, cameraNear, cameraFar );
+			if ( texture !== null ) {
+
+ 				node = depthBase().assign( texture );
+
+			} else {
+
+				if ( camera.isPerspectiveCamera ) {
+
+					node = viewZToPerspectiveDepth( positionView.z, cameraNear, cameraFar );
+
+				} else {
+
+					node = viewZToOrthographicDepth( positionView.z, cameraNear, cameraFar );
+
+				}
+
+			}
+
+		} else if ( scope === ViewportDepthNode.LINEAR_DEPTH ) {
+
+			if ( texture !== null ) {
+
+				if ( camera.isPerspectiveCamera ) {
+
+					const viewZ = perspectiveDepthToViewZ( texture, cameraNear, cameraFar );
 
 
-		} else if ( scope === ViewportDepthNode.DEPTH_TEXTURE ) {
+					node = viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
 
 
-			const texture = this.valueNode || viewportDepthTexture();
+				} else {
 
 
-			const viewZ = perspectiveDepthToViewZ( texture, cameraNear, cameraFar );
-			node = viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
+					node = texture;
 
 
-		} else if ( scope === ViewportDepthNode.DEPTH_PIXEL ) {
+				}
 
 
-			if ( this.valueNode !== null ) {
+			} else {
 
 
- 				node = depthPixelBase().assign( this.valueNode );
+				node = viewZToOrthographicDepth( positionView.z, cameraNear, cameraFar );
 
 
 			}
 			}
 
 
@@ -81,17 +105,16 @@ export const viewZToPerspectiveDepth = ( viewZ, near, far ) => near.add( viewZ )
 export const perspectiveDepthToViewZ = ( depth, near, far ) => near.mul( far ).div( far.sub( near ).mul( depth ).sub( far ) );
 export const perspectiveDepthToViewZ = ( depth, near, far ) => near.mul( far ).div( far.sub( near ).mul( depth ).sub( far ) );
 
 
 ViewportDepthNode.DEPTH = 'depth';
 ViewportDepthNode.DEPTH = 'depth';
-ViewportDepthNode.DEPTH_TEXTURE = 'depthTexture';
-ViewportDepthNode.DEPTH_PIXEL = 'depthPixel';
+ViewportDepthNode.LINEAR_DEPTH = 'linearDepth';
 
 
 export default ViewportDepthNode;
 export default ViewportDepthNode;
 
 
-const depthPixelBase = nodeProxy( ViewportDepthNode, ViewportDepthNode.DEPTH_PIXEL );
+const depthBase = nodeProxy( ViewportDepthNode, ViewportDepthNode.DEPTH );
 
 
 export const depth = nodeImmutable( ViewportDepthNode, ViewportDepthNode.DEPTH );
 export const depth = nodeImmutable( ViewportDepthNode, ViewportDepthNode.DEPTH );
-export const depthTexture = nodeProxy( ViewportDepthNode, ViewportDepthNode.DEPTH_TEXTURE );
-export const depthPixel = nodeImmutable( ViewportDepthNode, ViewportDepthNode.DEPTH_PIXEL );
+export const linearDepth = nodeProxy( ViewportDepthNode, ViewportDepthNode.LINEAR_DEPTH );
+export const viewportLinearDepth = linearDepth( viewportDepthTexture() );
 
 
-depthPixel.assign = ( value ) => depthPixelBase( value );
+depth.assign = ( value ) => depthBase( value );
 
 
 addNodeClass( 'ViewportDepthNode', ViewportDepthNode );
 addNodeClass( 'ViewportDepthNode', ViewportDepthNode );

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

@@ -20,7 +20,7 @@ import AONode from '../lighting/AONode.js';
 import { lightingContext } from '../lighting/LightingContextNode.js';
 import { lightingContext } from '../lighting/LightingContextNode.js';
 import EnvironmentNode from '../lighting/EnvironmentNode.js';
 import EnvironmentNode from '../lighting/EnvironmentNode.js';
 import IrradianceNode from '../lighting/IrradianceNode.js';
 import IrradianceNode from '../lighting/IrradianceNode.js';
-import { depthPixel } from '../display/ViewportDepthNode.js';
+import { depth } from '../display/ViewportDepthNode.js';
 import { cameraLogDepth } from '../accessors/CameraNode.js';
 import { cameraLogDepth } from '../accessors/CameraNode.js';
 import { clipping, clippingAlpha } from '../accessors/ClippingNode.js';
 import { clipping, clippingAlpha } from '../accessors/ClippingNode.js';
 import { faceDirection } from '../display/FrontFacingNode.js';
 import { faceDirection } from '../display/FrontFacingNode.js';
@@ -189,7 +189,7 @@ class NodeMaterial extends Material {
 
 
 		if ( depthNode !== null ) {
 		if ( depthNode !== null ) {
 
 
-			depthPixel.assign( depthNode ).append();
+			depth.assign( depthNode ).append();
 
 
 		}
 		}
 
 

+ 3 - 1
examples/jsm/renderers/common/nodes/Nodes.js

@@ -107,8 +107,10 @@ class Nodes extends DataMap {
 
 
 			if ( nodeBuilderState === undefined ) {
 			if ( nodeBuilderState === undefined ) {
 
 
-				const nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer, renderObject.scene );
+				const nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer );
+				nodeBuilder.scene = renderObject.scene;
 				nodeBuilder.material = renderObject.material;
 				nodeBuilder.material = renderObject.material;
+				nodeBuilder.camera = renderObject.camera;
 				nodeBuilder.context.material = renderObject.material;
 				nodeBuilder.context.material = renderObject.material;
 				nodeBuilder.lightsNode = renderObject.lightsNode;
 				nodeBuilder.lightsNode = renderObject.lightsNode;
 				nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene );
 				nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene );

+ 2 - 2
examples/jsm/renderers/webgl/WebGLBackend.js

@@ -787,9 +787,9 @@ class WebGLBackend extends Backend {
 
 
 	// node builder
 	// node builder
 
 
-	createNodeBuilder( object, renderer, scene = null ) {
+	createNodeBuilder( object, renderer ) {
 
 
-		return new GLSLNodeBuilder( object, renderer, scene );
+		return new GLSLNodeBuilder( object, renderer );
 
 
 	}
 	}
 
 

+ 2 - 2
examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js

@@ -47,9 +47,9 @@ precision lowp sampler2DShadow;
 
 
 class GLSLNodeBuilder extends NodeBuilder {
 class GLSLNodeBuilder extends NodeBuilder {
 
 
-	constructor( object, renderer, scene = null ) {
+	constructor( object, renderer ) {
 
 
-		super( object, renderer, new GLSLNodeParser(), scene );
+		super( object, renderer, new GLSLNodeParser() );
 
 
 		this.uniformGroups = {};
 		this.uniformGroups = {};
 		this.transforms = [];
 		this.transforms = [];

+ 2 - 2
examples/jsm/renderers/webgpu/WebGPUBackend.js

@@ -1163,9 +1163,9 @@ class WebGPUBackend extends Backend {
 
 
 	// node builder
 	// node builder
 
 
-	createNodeBuilder( object, renderer, scene = null ) {
+	createNodeBuilder( object, renderer ) {
 
 
-		return new WGSLNodeBuilder( object, renderer, scene );
+		return new WGSLNodeBuilder( object, renderer );
 
 
 	}
 	}
 
 

+ 2 - 2
examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js

@@ -155,9 +155,9 @@ fn threejs_biquadraticTexture( map : texture_2d<f32>, coord : vec2f, level : i32
 
 
 class WGSLNodeBuilder extends NodeBuilder {
 class WGSLNodeBuilder extends NodeBuilder {
 
 
-	constructor( object, renderer, scene = null ) {
+	constructor( object, renderer ) {
 
 
-		super( object, renderer, new WGSLNodeParser(), scene );
+		super( object, renderer, new WGSLNodeParser() );
 
 
 		this.uniformGroups = {};
 		this.uniformGroups = {};
 
 

二进制
examples/screenshots/webgpu_backdrop_area.jpg


二进制
examples/screenshots/webgpu_backdrop_water.jpg


+ 7 - 3
examples/webgpu_backdrop_area.html

@@ -25,7 +25,7 @@
 		<script type="module">
 		<script type="module">
 
 
 			import * as THREE from 'three';
 			import * as THREE from 'three';
-			import { color, depth, depthTexture, toneMapping, viewportSharedTexture, viewportMipTexture, viewportTopLeft, checker, uv, modelScale, MeshBasicNodeMaterial } from 'three/nodes';
+			import { color, linearDepth, toneMapping, viewportLinearDepth, viewportSharedTexture, viewportMipTexture, viewportTopLeft, checker, uv, modelScale, MeshBasicNodeMaterial } from 'three/nodes';
 
 
 			import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 			import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 
 
@@ -79,8 +79,12 @@
 
 
 				// volume
 				// volume
 
 
-				const depthDistance = depthTexture().distance( depth );
-				const depthAlphaNode = depthDistance.oneMinus().smoothstep( .90, 2 ).mul( 20 ).saturate();
+				// compare depth from viewportLinearDepth with linearDepth() to create a distance field
+				// viewportLinearDepth return the linear depth of the scene
+				// linearDepth() returns the linear depth of the mesh
+				const depthDistance = viewportLinearDepth.distance( linearDepth() );
+
+				const depthAlphaNode = depthDistance.oneMinus().smoothstep( .90, 2 ).mul( 10 ).saturate();
 				const depthBlurred = viewportMipTexture().bicubic( depthDistance.smoothstep( 0, .6 ).mul( 40 * 5 ).clamp( 0, 5 ) );
 				const depthBlurred = viewportMipTexture().bicubic( depthDistance.smoothstep( 0, .6 ).mul( 40 * 5 ).clamp( 0, 5 ) );
 
 
 				const blurredBlur = new MeshBasicNodeMaterial();
 				const blurredBlur = new MeshBasicNodeMaterial();

+ 6 - 3
examples/webgpu_backdrop_water.html

@@ -25,7 +25,7 @@
 		<script type="module">
 		<script type="module">
 
 
 			import * as THREE from 'three';
 			import * as THREE from 'three';
-			import { color, depth, vec2, pass, depthTexture, normalWorld, triplanarTexture, texture, objectPosition, viewportTopLeft, viewportDepthTexture, viewportSharedTexture, mx_worley_noise_float, positionWorld, timerLocal, MeshStandardNodeMaterial, MeshBasicNodeMaterial } from 'three/nodes';
+			import { color, vec2, pass, linearDepth, normalWorld, triplanarTexture, texture, objectPosition, viewportTopLeft, viewportLinearDepth, viewportDepthTexture, viewportSharedTexture, mx_worley_noise_float, positionWorld, timerLocal, MeshStandardNodeMaterial, MeshBasicNodeMaterial } from 'three/nodes';
 
 
 			import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
 			import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
 
 
@@ -157,12 +157,15 @@
 				const waterIntensity = waterLayer0.mul( waterLayer1 );
 				const waterIntensity = waterLayer0.mul( waterLayer1 );
 				const waterColor = waterIntensity.mul( 1.4 ).mix( color( 0x0487e2 ), color( 0x74ccf4 ) );
 				const waterColor = waterIntensity.mul( 1.4 ).mix( color( 0x0487e2 ), color( 0x74ccf4 ) );
 
 
-				const depthWater = depthTexture( viewportDepthTexture() ).sub( depth );
+				// linearDepth() returns the linear depth of the mesh
+				const depth = linearDepth();
+				const depthWater = viewportLinearDepth.sub( depth );
 				const depthEffect = depthWater.remapClamp( - .002, .04 );
 				const depthEffect = depthWater.remapClamp( - .002, .04 );
 
 
 				const refractionUV = viewportTopLeft.add( vec2( 0, waterIntensity.mul( .1 ) ) );
 				const refractionUV = viewportTopLeft.add( vec2( 0, waterIntensity.mul( .1 ) ) );
 
 
-				const depthTestForRefraction = depthTexture( viewportDepthTexture( refractionUV ) ).sub( depth );
+				// linearDepth( viewportDepthTexture( uv ) ) return the linear depth of the scene
+				const depthTestForRefraction = linearDepth( viewportDepthTexture( refractionUV ) ).sub( depth );
 
 
 				const depthRefraction = depthTestForRefraction.remapClamp( 0, .1 );
 				const depthRefraction = depthTestForRefraction.remapClamp( 0, .1 );