Przeglądaj źródła

Node: Document more modules. (#30137)

Michael Herzog 1 rok temu
rodzic
commit
d23dffc843

+ 111 - 0
examples/jsm/tsl/display/AnamorphicNode.js

@@ -1,10 +1,17 @@
 import { RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, PostProcessingUtils } from 'three/webgpu';
 import { nodeObject, Fn, float, NodeUpdateType, uv, passTexture, uniform, convertToTexture, vec2, vec3, Loop, mix, luminance } from 'three/tsl';
 
+/** @module AnaglyphPassNode **/
+
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 
 let _rendererState;
 
+/**
+ * Post processing node for adding an anamorphic flare effect.
+ *
+ * @augments TempNode
+ */
 class AnamorphicNode extends TempNode {
 
 	static get type() {
@@ -13,34 +20,113 @@ class AnamorphicNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new anamorphic node.
+	 *
+	 * @param {TextureNode} textureNode - The texture node that represents the input of the effect.
+	 * @param {Node<float>} tresholdNode - The threshold is one option to control the intensity and size of the effect.
+	 * @param {Node<float>} scaleNode - Defines the vertical scale of the flares.
+	 * @param {Number} samples - More samples result in larger flares and a more expensive runtime behavior.
+	 */
 	constructor( textureNode, tresholdNode, scaleNode, samples ) {
 
 		super( 'vec4' );
 
+		/**
+		 * The texture node that represents the input of the effect.
+		 *
+		 * @type {TextureNode}
+		 */
 		this.textureNode = textureNode;
+
+		/**
+		 * The threshold is one option to control the intensity and size of the effect.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.tresholdNode = tresholdNode;
+
+		/**
+		 * Defines the vertical scale of the flares.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.scaleNode = scaleNode;
+
+		/**
+		 * The color of the flares.
+		 *
+		 * @type {Node<vec3>}
+		 */
 		this.colorNode = vec3( 0.1, 0.0, 1.0 );
+
+		/**
+		 * More samples result in larger flares and a more expensive runtime behavior.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.samples = samples;
+
+		/**
+		 * The resolution scale.
+		 *
+		 * @type {Vector2}
+		 */
 		this.resolution = new Vector2( 1, 1 );
 
+		/**
+		 * The internal render target of the effect.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTarget = new RenderTarget( 1, 1, { depthBuffer: false } );
 		this._renderTarget.texture.name = 'anamorphic';
 
+		/**
+		 * A uniform node holding the inverse resolution value.
+		 *
+		 * @private
+		 * @type {UniformNode<vec2>}
+		 */
 		this._invSize = uniform( new Vector2() );
 
+		/**
+		 * The result of the effect is represented as a separate texture node.
+		 *
+		 * @private
+		 * @type {PassTextureNode}
+		 */
 		this._textureNode = passTexture( this, this._renderTarget.texture );
 
+		/**
+		 * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
+		 * its effect once per frame in `updateBefore()`.
+		 *
+		 * @type {String}
+		 * @default 'frame'
+		 */
 		this.updateBeforeType = NodeUpdateType.FRAME;
 
 	}
 
+	/**
+	 * Returns the result of the effect as a texture node.
+	 *
+	 * @return {PassTextureNode} A texture node that represents the result of the effect.
+	 */
 	getTextureNode() {
 
 		return this._textureNode;
 
 	}
 
+	/**
+	 * Sets the size of the effect.
+	 *
+	 * @param {Number} width - The width of the effect.
+	 * @param {Number} height - The height of the effect.
+	 */
 	setSize( width, height ) {
 
 		this._invSize.value.set( 1 / width, 1 / height );
@@ -52,6 +138,11 @@ class AnamorphicNode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to render the effect once per frame.
+	 *
+	 * @param {NodeFrame} frame - The current node frame.
+	 */
 	updateBefore( frame ) {
 
 		const { renderer } = frame;
@@ -85,6 +176,12 @@ class AnamorphicNode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to setup the effect's TSL code.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {PassTextureNode}
+	 */
 	setup( builder ) {
 
 		const textureNode = this.textureNode;
@@ -134,6 +231,10 @@ class AnamorphicNode extends TempNode {
 
 	}
 
+	/**
+	 * Frees internal resources. This method should be called
+	 * when the effect is no longer required.
+	 */
 	dispose() {
 
 		this._renderTarget.dispose();
@@ -142,6 +243,16 @@ class AnamorphicNode extends TempNode {
 
 }
 
+/**
+ * TSL function for creating an anamorphic flare effect.
+ *
+ * @function
+ * @param {TextureNode} node - The node that represents the input of the effect.
+ * @param {Node<float> | Number} [threshold=0.9] - The threshold is one option to control the intensity and size of the effect.
+ * @param {Node<float> | Number} [scale=3] - Defines the vertical scale of the flares.
+ * @param {Number} [samples=32] - More samples result in larger flares and a more expensive runtime behavior.
+ * @returns {AnamorphicNode}
+ */
 export const anamorphic = ( node, threshold = .9, scale = 3, samples = 32 ) => nodeObject( new AnamorphicNode( convertToTexture( node ), nodeObject( threshold ), nodeObject( scale ), samples ) );
 
 export default AnamorphicNode;

+ 218 - 11
examples/jsm/tsl/display/BloomNode.js

@@ -1,6 +1,8 @@
 import { HalfFloatType, RenderTarget, Vector2, Vector3, TempNode, QuadMesh, NodeMaterial, PostProcessingUtils, NodeUpdateType } from 'three/webgpu';
 import { nodeObject, Fn, float, uv, passTexture, uniform, Loop, texture, luminance, smoothstep, mix, vec4, uniformArray, add, int } from 'three/tsl';
 
+/** @module BloomNode **/
+
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 const _size = /*@__PURE__*/ new Vector2();
 
@@ -9,6 +11,38 @@ const _BlurDirectionY = /*@__PURE__*/ new Vector2( 0.0, 1.0 );
 
 let _rendererState;
 
+/**
+ * Post processing node for creating a bloom effect.
+ * ```js
+ * const postProcessing = new THREE.PostProcessing( renderer );
+ *
+ * const scenePass = pass( scene, camera );
+ * const scenePassColor = scenePass.getTextureNode( 'output' );
+ *
+ * const bloomPass = bloom( scenePassColor );
+ *
+ * postProcessing.outputNode = scenePassColor.add( bloomPass );
+ * ```
+ * By default, the node affects the entire image. For a selective bloom,
+ * use the `emissive` material property to control which objects should
+ * contribute to bloom or not. This can be achieved via MRT.
+ * ```js
+ * const postProcessing = new THREE.PostProcessing( renderer );
+ *
+ * const scenePass = pass( scene, camera );
+ * scenePass.setMRT( mrt( {
+ * 	output,
+ * 	emissive
+ * } ) );
+ *
+ * const scenePassColor = scenePass.getTextureNode( 'output' );
+ * const emissivePass = scenePass.getTextureNode( 'emissive' );
+ *
+ * const bloomPass = bloom( emissivePass );
+ * postProcessing.outputNode = scenePassColor.add( bloomPass );
+ * ```
+ * @augments TempNode
+ */
 class BloomNode extends TempNode {
 
 	static get type() {
@@ -17,29 +51,89 @@ class BloomNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new bloom node.
+	 *
+	 * @param {Node<vec4>} inputNode - The node that represents the input of the effect.
+	 * @param {Number} [strength=1] - The strength of the bloom.
+	 * @param {Number} [radius=0] - The radius of the bloom.
+	 * @param {Number} [threshold=0] - The luminance threshold limits which bright areas contribute to the bloom effect.
+	 */
 	constructor( inputNode, strength = 1, radius = 0, threshold = 0 ) {
 
 		super( 'vec4' );
 
+		/**
+		 * The node that represents the input of the effect.
+		 *
+		 * @type {Node<vec4>}
+		 */
 		this.inputNode = inputNode;
+
+		/**
+		 * The strength of the bloom.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.strength = uniform( strength );
+
+		/**
+		 * The radius of the bloom.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.radius = uniform( radius );
+
+		/**
+		 * The luminance threshold limits which bright areas contribute to the bloom effect.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.threshold = uniform( threshold );
 
+		/**
+		 * Can be used to tweak the extracted luminance from the scene.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.smoothWidth = uniform( 0.01 );
 
-		//
-
+		/**
+		 * An array that holds the render targets for the horizonal blur passes.
+		 *
+		 * @private
+		 * @type {Array<RenderTarget>}
+		 */
 		this._renderTargetsHorizontal = [];
+
+		/**
+		 * An array that holds the render targets for the vertical blur passes.
+		 *
+		 * @private
+		 * @type {Array<RenderTarget>}
+		 */
 		this._renderTargetsVertical = [];
-		this._nMips = 5;
 
-		// render targets
+		/**
+		 * The number if blur mips.
+		 *
+		 * @private
+		 * @type {Number}
+		 */
+		this._nMips = 5;
 
+		/**
+		 * The render target for the luminance pass.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTargetBright = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType } );
 		this._renderTargetBright.texture.name = 'UnrealBloomPass.bright';
 		this._renderTargetBright.texture.generateMipmaps = false;
 
+		//
+
 		for ( let i = 0; i < this._nMips; i ++ ) {
 
 			const renderTargetHorizontal = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType } );
@@ -58,33 +152,114 @@ class BloomNode extends TempNode {
 
 		}
 
-		// materials
-
+		/**
+		 * The material for the composite pass.
+		 *
+		 * @private
+		 * @type {NodeMaterial?}
+		 */
 		this._compositeMaterial = null;
+
+		/**
+		 * The material for the luminance pass.
+		 *
+		 * @private
+		 * @type {NodeMaterial?}
+		 */
 		this._highPassFilterMaterial = null;
-		this._separableBlurMaterials = [];
 
-		// pass and texture nodes
+		/**
+		 * The materials for the blur pass.
+		 *
+		 * @private
+		 * @type {Array<NodeMaterial>}
+		 */
+		this._separableBlurMaterials = [];
 
+		/**
+		 * The result of the luminance pass as a texture node for further processing.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._textureNodeBright = texture( this._renderTargetBright.texture );
+
+		/**
+		 * The result of the first blur pass as a texture node for further processing.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._textureNodeBlur0 = texture( this._renderTargetsVertical[ 0 ].texture );
+
+		/**
+		 * The result of the second blur pass as a texture node for further processing.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._textureNodeBlur1 = texture( this._renderTargetsVertical[ 1 ].texture );
+
+		/**
+		 * The result of the third blur pass as a texture node for further processing.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._textureNodeBlur2 = texture( this._renderTargetsVertical[ 2 ].texture );
+
+		/**
+		 * The result of the fourth blur pass as a texture node for further processing.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._textureNodeBlur3 = texture( this._renderTargetsVertical[ 3 ].texture );
+
+		/**
+		 * The result of the fifth blur pass as a texture node for further processing.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._textureNodeBlur4 = texture( this._renderTargetsVertical[ 4 ].texture );
 
+		/**
+		 * The result of the effect is represented as a separate texture node.
+		 *
+		 * @private
+		 * @type {PassTextureNode}
+		 */
 		this._textureOutput = passTexture( this, this._renderTargetsHorizontal[ 0 ].texture );
 
+		/**
+		 * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
+		 * its effect once per frame in `updateBefore()`.
+		 *
+		 * @type {String}
+		 * @default 'frame'
+		 */
 		this.updateBeforeType = NodeUpdateType.FRAME;
 
 	}
 
+	/**
+	 * Returns the result of the effect as a texture node.
+	 *
+	 * @return {PassTextureNode} A texture node that represents the result of the effect.
+	 */
 	getTextureNode() {
 
 		return this._textureOutput;
 
 	}
 
+	/**
+	 * Sets the size of the effect.
+	 *
+	 * @param {Number} width - The width of the effect.
+	 * @param {Number} height - The height of the effect.
+	 */
 	setSize( width, height ) {
 
 		let resx = Math.round( width / 2 );
@@ -106,6 +281,11 @@ class BloomNode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to render the effect once per frame.
+	 *
+	 * @param {NodeFrame} frame - The current node frame.
+	 */
 	updateBefore( frame ) {
 
 		const { renderer } = frame;
@@ -117,13 +297,13 @@ class BloomNode extends TempNode {
 		const size = renderer.getDrawingBufferSize( _size );
 		this.setSize( size.width, size.height );
 
-		// 1. Extract Bright Areas
+		// 1. Extract bright areas
 
 		renderer.setRenderTarget( this._renderTargetBright );
 		_quadMesh.material = this._highPassFilterMaterial;
 		_quadMesh.render( renderer );
 
-		// 2. Blur All the mips progressively
+		// 2. Blur all the mips progressively
 
 		let inputRenderTarget = this._renderTargetBright;
 
@@ -145,7 +325,7 @@ class BloomNode extends TempNode {
 
 		}
 
-		// 3. Composite All the mips
+		// 3. Composite all the mips
 
 		renderer.setRenderTarget( this._renderTargetsHorizontal[ 0 ] );
 		_quadMesh.material = this._compositeMaterial;
@@ -157,6 +337,12 @@ class BloomNode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to setup the effect's TSL code.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {PassTextureNode}
+	 */
 	setup( builder ) {
 
 		// luminosity high pass material
@@ -232,6 +418,10 @@ class BloomNode extends TempNode {
 
 	}
 
+	/**
+	 * Frees internal resources. This method should be called
+	 * when the effect is no longer required.
+	 */
 	dispose() {
 
 		for ( let i = 0; i < this._renderTargetsHorizontal.length; i ++ ) {
@@ -250,6 +440,13 @@ class BloomNode extends TempNode {
 
 	}
 
+	/**
+	 * Create a seperable blur material for the given kernel radius.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @param {Number} kernelRadius - The kernel radius.
+	 * @return {NodeMaterial}
+	 */
 	_getSeperableBlurMaterial( builder, kernelRadius ) {
 
 		const coefficients = [];
@@ -307,6 +504,16 @@ class BloomNode extends TempNode {
 
 }
 
+/**
+ * TSL function for creating a bloom effect.
+ *
+ * @function
+ * @param {Node<vec4>} node - The node that represents the input of the effect.
+ * @param {Number} [strength=1] - The strength of the bloom.
+ * @param {Number} [radius=0] - The radius of the bloom.
+ * @param {Number} [threshold=0] - The luminance threshold limits which bright areas contribute to the bloom effect.
+ * @returns {BloomNode}
+ */
 export const bloom = ( node, strength, radius, threshold ) => nodeObject( new BloomNode( nodeObject( node ), strength, radius, threshold ) );
 
 export default BloomNode;

+ 137 - 21
examples/jsm/tsl/display/DenoiseNode.js

@@ -2,6 +2,18 @@ import { DataTexture, RepeatWrapping, Vector2, Vector3, TempNode } from 'three/w
 import { texture, getNormalFromDepth, getViewPosition, convertToTexture, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, luminance, vec2, vec3, vec4, uniformArray, int, dot, max, pow, abs, If, textureSize, sin, cos, mat2, PI } from 'three/tsl';
 import { SimplexNoise } from '../../math/SimplexNoise.js';
 
+/** @module DenoiseNode **/
+
+/**
+ * Post processing node for denoising data like raw screen-space ambient occlusion output.
+ * Denoise can noticeably improve the quality of ambient occlusion but also add quite some
+ * overhead to the post processing setup. It's best to make its usage optional (e.g. via
+ * graphic settings).
+ *
+ * Reference: {@link https://openaccess.thecvf.com/content/WACV2021/papers/Khademi_Self-Supervised_Poisson-Gaussian_Denoising_WACV_2021_paper.pdf}.
+ *
+ * @augments TempNode
+ */
 class DenoiseNode extends TempNode {
 
 	static get type() {
@@ -10,32 +22,123 @@ class DenoiseNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new denoise node.
+	 *
+	 * @param {TextureNode} textureNode - The texture node that represents the input of the effect (e.g. AO).
+	 * @param {Node<float>} depthNode - A node that represents the scene's depth.
+	 * @param {Node<vec3>?} normalNode - A node that represents the scene's normals.
+	 * @param {Camera} camera - The camera the scene is rendered with.
+	 */
 	constructor( textureNode, depthNode, normalNode, camera ) {
 
 		super( 'vec4' );
 
+		/**
+		 * The texture node that represents the input of the effect (e.g. AO).
+		 *
+		 * @type {TextureNode}
+		 */
 		this.textureNode = textureNode;
+
+		/**
+		 * A node that represents the scene's depth.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.depthNode = depthNode;
+
+		/**
+		 * A node that represents the scene's normals. If no normals are passed to the
+		 * constructor (because MRT is not available), normals can be automatically
+		 * reconstructed from depth values in the shader.
+		 *
+		 * @type {Node<vec3>?}
+		 */
 		this.normalNode = normalNode;
 
+		/**
+		 * The node represents the internal noise texture.
+		 *
+		 * @type {TextureNode}
+		 */
 		this.noiseNode = texture( generateDefaultNoise() );
 
+		/**
+		 * The luma Phi value.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.lumaPhi = uniform( 5 );
+
+		/**
+		 * The depth Phi value.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.depthPhi = uniform( 5 );
+
+		/**
+		 * The normal Phi value.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.normalPhi = uniform( 5 );
+
+		/**
+		 * The radius.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.radius = uniform( 5 );
+
+		/**
+		 * The index.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.index = uniform( 0 );
 
+		/**
+		 * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node updates
+		 * its internal uniforms once per frame in `updateBefore()`.
+		 *
+		 * @type {String}
+		 * @default 'frame'
+		 */
 		this.updateBeforeType = NodeUpdateType.FRAME;
 
-		// uniforms
-
+		/**
+		 * The resolution of the effect.
+		 *
+		 * @private
+		 * @type {UniformNode<vec2>}
+		 */
 		this._resolution = uniform( new Vector2() );
-		this._sampleVectors = uniformArray( generatePdSamplePointInitializer( 16, 2, 1 ) );
+
+		/**
+		 * An array of sample vectors.
+		 *
+		 * @private
+		 * @type {UniformArrayNode<vec3>}
+		 */
+		this._sampleVectors = uniformArray( generateDenoiseSamples( 16, 2, 1 ) );
+
+		/**
+		 * Represents the inverse projection matrix of the scene's camera.
+		 *
+		 * @private
+		 * @type {UniformNode<mat4>}
+		 */
 		this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
 
 	}
 
+	/**
+	 * This method is used to update internal uniforms once per frame.
+	 *
+	 * @param {NodeFrame} frame - The current node frame.
+	 */
 	updateBefore() {
 
 		const map = this.textureNode.value;
@@ -44,7 +147,13 @@ class DenoiseNode extends TempNode {
 
 	}
 
-	setup() {
+	/**
+	 * This method is used to setup the effect's TSL code.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {ShaderCallNodeInternal}
+	 */
+	setup( /* builder */ ) {
 
 		const uvNode = uv();
 
@@ -149,23 +258,14 @@ class DenoiseNode extends TempNode {
 
 export default DenoiseNode;
 
-function generatePdSamplePointInitializer( samples, rings, radiusExponent ) {
-
-	const poissonDisk = generateDenoiseSamples( samples, rings, radiusExponent );
-
-	const array = [];
-
-	for ( let i = 0; i < samples; i ++ ) {
-
-		const sample = poissonDisk[ i ];
-		array.push( sample );
-
-	}
-
-	return array;
-
-}
-
+/**
+ * Generates denoise samples based on the given parameters.
+ *
+ * @param {Number} numSamples - The number of samples.
+ * @param {Number} numRings - The number of rings.
+ * @param {Number} radiusExponent - The radius exponent.
+ * @return {Array<Vector3>} The denoise samples.
+ */
 function generateDenoiseSamples( numSamples, numRings, radiusExponent ) {
 
 	const samples = [];
@@ -182,6 +282,12 @@ function generateDenoiseSamples( numSamples, numRings, radiusExponent ) {
 
 }
 
+/**
+ * Generates a default noise texture for the given size.
+ *
+ * @param {Number} [size=64] - The texture size.
+ * @return {DataTexture} The generated noise texture.
+ */
 function generateDefaultNoise( size = 64 ) {
 
 	const simplex = new SimplexNoise();
@@ -214,4 +320,14 @@ function generateDefaultNoise( size = 64 ) {
 
 }
 
+/**
+ * TSL function for creating a denoise effect.
+ *
+ * @function
+ * @param {Node} node - The node that represents the input of the effect (e.g. AO).
+ * @param {Node<float>} depthNode - A node that represents the scene's depth.
+ * @param {Node<vec3>?} normalNode - A node that represents the scene's normals.
+ * @param {Camera} camera - The camera the scene is rendered with.
+ * @returns {DenoiseNode}
+ */
 export const denoise = ( node, depthNode, normalNode, camera ) => nodeObject( new DenoiseNode( convertToTexture( node ), nodeObject( depthNode ), nodeObject( normalNode ), camera ) );

+ 204 - 8
examples/jsm/tsl/display/GTAONode.js

@@ -1,14 +1,36 @@
 import { DataTexture, RenderTarget, RepeatWrapping, Vector2, Vector3, TempNode, QuadMesh, NodeMaterial, PostProcessingUtils } from 'three/webgpu';
 import { reference, logarithmicDepthToViewZ, viewZToPerspectiveDepth, getNormalFromDepth, getScreenPosition, getViewPosition, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, vec2, vec3, vec4, int, dot, max, pow, abs, If, textureSize, sin, cos, PI, texture, passTexture, mat3, add, normalize, mul, cross, div, mix, sqrt, sub, acos, clamp } from 'three/tsl';
 
+/** @module GTAONode **/
+
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 const _size = /*@__PURE__*/ new Vector2();
 
 let _rendererState;
 
 /**
- * References:
- * https://www.activision.com/cdn/research/Practical_Real_Time_Strategies_for_Accurate_Indirect_Occlusion_NEW%20VERSION_COLOR.pdf
+ * Post processing node for applying Ground Truth Ambient Occlusion (GTAO) to a scene.
+ * ```js
+ * const postProcessing = new THREE.PostProcessing( renderer );
+ *
+ * const scenePass = pass( scene, camera );
+ * scenePass.setMRT( mrt( {
+ * 	output: output,
+ * 	normal: normalView
+ * } ) );
+ *
+ * const scenePassColor = scenePass.getTextureNode( 'output' );
+ * const scenePassNormal = scenePass.getTextureNode( 'normal' );
+ * const scenePassDepth = scenePass.getTextureNode( 'depth' );
+ *
+ * const aoPass = ao( scenePassDepth, scenePassNormal, camera );
+ *
+ * postProcessing.outputNod = aoPass.getTextureNode().mul( scenePassColor );
+ * ```
+ *
+ * Reference: {@link https://www.activision.com/cdn/research/Practical_Real_Time_Strategies_for_Accurate_Indirect_Occlusion_NEW%20VERSION_COLOR.pdf}.
+ *
+ * @augments TempNode
  */
 class GTAONode extends TempNode {
 
@@ -18,55 +40,193 @@ class GTAONode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new GTAO node.
+	 *
+	 * @param {Node<float>} depthNode - A node that represents the scene's depth.
+	 * @param {Node<vec3>?} normalNode - A node that represents the scene's normals.
+	 * @param {Camera} camera - The camera the scene is rendered with.
+	 */
 	constructor( depthNode, normalNode, camera ) {
 
 		super( 'vec4' );
 
+		/**
+		 * A node that represents the scene's depth.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.depthNode = depthNode;
+
+		/**
+		 * A node that represents the scene's normals. If no normals are passed to the
+		 * constructor (because MRT is not available), normals can be automatically
+		 * reconstructed from depth values in the shader.
+		 *
+		 * @type {Node<vec3>?}
+		 */
 		this.normalNode = normalNode;
 
+		/**
+		 * The resolution scale. By default the effect is rendered in full resolution
+		 * for best quality but a value of `0.5` should be sufficient for most scenes.
+		 *
+		 * @type {Number}
+		 * @default 1
+		 */
 		this.resolutionScale = 1;
 
+		/**
+		 * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
+		 * its effect once per frame in `updateBefore()`.
+		 *
+		 * @type {String}
+		 * @default 'frame'
+		 */
 		this.updateBeforeType = NodeUpdateType.FRAME;
 
-		// render targets
-
+		/**
+		 * The render target the ambient occlusion is rendered into.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._aoRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false } );
 		this._aoRenderTarget.texture.name = 'GTAONode.AO';
 
 		// uniforms
 
+		/**
+		 * The radius of the ambient occlusion.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.radius = uniform( 0.25 );
+
+		/**
+		 * The resolution of the effect. Can be scaled via
+		 * `resolutionScale`.
+		 *
+		 * @type {UniformNode<vec2>}
+		 */
 		this.resolution = uniform( new Vector2() );
+
+		/**
+		 * The thickness of the ambient occlusion.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.thickness = uniform( 1 );
+
+		/**
+		 * Another option to tweak the occlusion. The recommended range is
+		 * `[1,2]` for attenuating the AO.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.distanceExponent = uniform( 1 );
+
+		/**
+		 * The distance fall off value of the ambient occlusion.
+		 * A lower value leads to a larget AO effect. The value
+		 * should lie in the range `[0,1]`.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.distanceFallOff = uniform( 1 );
+
+		/**
+		 * The scale of the ambient occlusion.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.scale = uniform( 1 );
+
+		/**
+		 * How many samples are used to compute the AO.
+		 * A higher value results in better quality but also
+		 * in a more expensive runtime behavior.
+		 *
+		 * @type {UniformNode<float>}
+		 */
 		this.samples = uniform( 16 );
 
+		/**
+		 * The node represents the internal noise texture used by the AO.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._noiseNode = texture( generateMagicSquareNoise() );
+
+		/**
+		 * Represents the projection matrix of the scene's camera.
+		 *
+		 * @private
+		 * @type {UniformNode<mat4>}
+		 */
 		this._cameraProjectionMatrix = uniform( camera.projectionMatrix );
+
+		/**
+		 * Represents the inverse projection matrix of the scene's camera.
+		 *
+		 * @private
+		 * @type {UniformNode<mat4>}
+		 */
 		this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
+
+		/**
+		 * Represents the near value of the scene's camera.
+		 *
+		 * @private
+		 * @type {ReferenceNode<float>}
+		 */
 		this._cameraNear = reference( 'near', 'float', camera );
-		this._cameraFar = reference( 'far', 'float', camera );
 
-		// materials
+		/**
+		 * Represents the far value of the scene's camera.
+		 *
+		 * @private
+		 * @type {ReferenceNode<float>}
+		 */
+		this._cameraFar = reference( 'far', 'float', camera );
 
+		/**
+		 * The material that is used to render the effect.
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._material = new NodeMaterial();
 		this._material.name = 'GTAO';
 
-		//
-
+		/**
+		 * The result of the effect is represented as a separate texture node.
+		 *
+		 * @private
+		 * @type {PassTextureNode}
+		 */
 		this._textureNode = passTexture( this, this._aoRenderTarget.texture );
 
 	}
 
+	/**
+	 * Returns the result of the effect as a texture node.
+	 *
+	 * @return {PassTextureNode} A texture node that represents the result of the effect.
+	 */
 	getTextureNode() {
 
 		return this._textureNode;
 
 	}
 
+	/**
+	 * Sets the size of the effect.
+	 *
+	 * @param {Number} width - The width of the effect.
+	 * @param {Number} height - The height of the effect.
+	 */
 	setSize( width, height ) {
 
 		width = Math.round( this.resolutionScale * width );
@@ -77,6 +237,11 @@ class GTAONode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to render the effect once per frame.
+	 *
+	 * @param {NodeFrame} frame - The current node frame.
+	 */
 	updateBefore( frame ) {
 
 		const { renderer } = frame;
@@ -105,6 +270,12 @@ class GTAONode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to setup the effect's TSL code.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {PassTextureNode}
+	 */
 	setup( builder ) {
 
 		const uvNode = uv();
@@ -227,6 +398,10 @@ class GTAONode extends TempNode {
 
 	}
 
+	/**
+	 * Frees internal resources. This method should be called
+	 * when the effect is no longer required.
+	 */
 	dispose() {
 
 		this._aoRenderTarget.dispose();
@@ -239,6 +414,12 @@ class GTAONode extends TempNode {
 
 export default GTAONode;
 
+/**
+ * Generates the AO's noise texture for the given size.
+ *
+ * @param {Number} [size=5] - The noise size.
+ * @return {DataTexture} The generated noise texture.
+ */
 function generateMagicSquareNoise( size = 5 ) {
 
 	const noiseSize = Math.floor( size ) % 2 === 0 ? Math.floor( size ) + 1 : Math.floor( size );
@@ -271,6 +452,12 @@ function generateMagicSquareNoise( size = 5 ) {
 
 }
 
+/**
+ * Computes an array of magic square values required to generate the noise texture.
+ *
+ * @param {Number} size - The noise size.
+ * @return {Array<Number>} The magic square values.
+ */
 function generateMagicSquare( size ) {
 
 	const noiseSize = Math.floor( size ) % 2 === 0 ? Math.floor( size ) + 1 : Math.floor( size );
@@ -323,4 +510,13 @@ function generateMagicSquare( size ) {
 
 }
 
+/**
+ * TSL function for creating a Ground Truth Ambient Occlusion (GTAO) effect.
+ *
+ * @function
+ * @param {Node<float>} depthNode - A node that represents the scene's depth.
+ * @param {Node<vec3>?} normalNode - A node that represents the scene's normals.
+ * @param {Camera} camera - The camera the scene is rendered with.
+ * @returns {GTAONode}
+ */
 export const ao = ( depthNode, normalNode, camera ) => nodeObject( new GTAONode( nodeObject( depthNode ), nodeObject( normalNode ), camera ) );

+ 2 - 2
examples/jsm/tsl/display/GaussianBlurNode.js

@@ -371,7 +371,7 @@ class GaussianBlurNode extends TempNode {
 export default GaussianBlurNode;
 
 /**
- * TSL function for creating gaussian blur node for post processing.
+ * TSL function for creating a gaussian blur node for post processing.
  *
  * @function
  * @param {Node<vec4>} node - The node that represents the input of the effect.
@@ -382,7 +382,7 @@ export default GaussianBlurNode;
 export const gaussianBlur = ( node, directionNode, sigma ) => nodeObject( new GaussianBlurNode( convertToTexture( node ), directionNode, sigma ) );
 
 /**
- * TSL function for creating gaussian blur node for post processing with enabled premultiplied alpha.
+ * TSL function for creating a gaussian blur node for post processing with enabled premultiplied alpha.
  *
  * @function
  * @param {Node<vec4>} node - The node that represents the input of the effect.

+ 127 - 9
examples/jsm/tsl/display/LensflareNode.js

@@ -1,14 +1,21 @@
 import { RenderTarget, Vector2, TempNode, NodeUpdateType, QuadMesh, PostProcessingUtils, NodeMaterial } from 'three/webgpu';
 import { convertToTexture, nodeObject, Fn, passTexture, uv, vec2, vec3, vec4, max, float, sub, int, Loop, fract, pow, distance } from 'three/tsl';
 
+/** @module LensflareNode **/
+
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 const _size = /*@__PURE__*/ new Vector2();
 let _rendererState;
 
 /**
+ * Post processing node for adding a bloom-based lens flare effect. This effect
+ * requires that you extract the bloom of the scene via a bloom pass first.
+ *
  * References:
- * https://john-chapman-graphics.blogspot.com/2013/02/pseudo-lens-flare.html
- * https://john-chapman.github.io/2017/11/05/pseudo-lens-flare.html
+ * - {@link https://john-chapman-graphics.blogspot.com/2013/02/pseudo-lens-flare.html}.
+ * - {@link https://john-chapman.github.io/2017/11/05/pseudo-lens-flare.html}.
+ *
+ * @augments TempNode
  */
 class LensflareNode extends TempNode {
 
@@ -18,10 +25,27 @@ class LensflareNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new lens flare node.
+	 *
+	 * @param {TextureNode} textureNode - The texture node that represents the scene's bloom.
+	 * @param {Object} params - The parameter object for configuring the effect.
+	 * @param {Node<vec3> | Color} [params.ghostTint=vec3(1, 1, 1)] - Defines the tint of the flare/ghosts.
+	 * @param {Node<float> | Number} [params.threshold=float(0.5)] - Controls the size and strength of the effect. A higher threshold results in smaller flares.
+	 * @param {Node<float> | Number} [params.ghostSamples=float(4)] - Represents the number of flares/ghosts per bright spot which pivot around the center.
+	 * @param {Node<float> | Number} [params.ghostSpacing=float(0.25)] - Defines the spacing of the flares/ghosts.
+	 * @param {Node<float> | Number} [params.ghostAttenuationFactor=float(25)] - Defines the attenuation factor of flares/ghosts.
+	 * @param {Number} [params.downSampleRatio=4] - Defines how downsampling since the effect is usually not rendered at full resolution.
+	 */
 	constructor( textureNode, params = {} ) {
 
 		super( 'vec4' );
 
+		/**
+		 * The texture node that represents the scene's bloom.
+		 *
+		 * @type {TextureNode}
+		 */
 		this.textureNode = textureNode;
 
 		const {
@@ -33,37 +57,102 @@ class LensflareNode extends TempNode {
 			downSampleRatio = 4
 		} = params;
 
+		/**
+		 * Defines the tint of the flare/ghosts.
+		 *
+		 * @type {Node<vec3>}
+		 */
 		this.ghostTintNode = nodeObject( ghostTint );
+
+		/**
+		 * Controls the size and strength of the effect. A higher threshold results in smaller flares.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.thresholdNode = nodeObject( threshold );
+
+		/**
+		 * Represents the number of flares/ghosts per bright spot which pivot around the center.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.ghostSamplesNode = nodeObject( ghostSamples );
+
+		/**
+		 * Defines the spacing of the flares/ghosts.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.ghostSpacingNode = nodeObject( ghostSpacing );
+
+		/**
+		 * Defines the attenuation factor of flares/ghosts.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.ghostAttenuationFactorNode = nodeObject( ghostAttenuationFactor );
+
+		/**
+		 * Defines how downsampling since the effect is usually not rendered at full resolution.
+		 *
+		 * @type {Number}
+		 */
 		this.downSampleRatio = downSampleRatio;
 
+		/**
+		 * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
+		 * its effect once per frame in `updateBefore()`.
+		 *
+		 * @type {String}
+		 * @default 'frame'
+		 */
 		this.updateBeforeType = NodeUpdateType.FRAME;
 
-		// render targets
-
+		/**
+		 * The internal render target of the effect.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTarget = new RenderTarget( 1, 1, { depthBuffer: false } );
 		this._renderTarget.texture.name = 'LensflareNode';
 
-		// materials
-
+		/**
+		 * The node material that holds the effect's TSL code.
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._material = new NodeMaterial();
 		this._material.name = 'LensflareNode';
 
-		//
-
+		/**
+		 * The result of the effect is represented as a separate texture node.
+		 *
+		 * @private
+		 * @type {PassTextureNode}
+		 */
 		this._textureNode = passTexture( this, this._renderTarget.texture );
 
 	}
 
+	/**
+	 * Returns the result of the effect as a texture node.
+	 *
+	 * @return {PassTextureNode} A texture node that represents the result of the effect.
+	 */
 	getTextureNode() {
 
 		return this._textureNode;
 
 	}
 
+	/**
+	 * Sets the size of the effect.
+	 *
+	 * @param {Number} width - The width of the effect.
+	 * @param {Number} height - The height of the effect.
+	 */
 	setSize( width, height ) {
 
 		const resx = Math.round( width / this.downSampleRatio );
@@ -73,6 +162,11 @@ class LensflareNode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to render the effect once per frame.
+	 *
+	 * @param {NodeFrame} frame - The current node frame.
+	 */
 	updateBefore( frame ) {
 
 		const { renderer } = frame;
@@ -99,6 +193,12 @@ class LensflareNode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to setup the effect's TSL code.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {PassTextureNode}
+	 */
 	setup( builder ) {
 
 		const lensflare = Fn( () => {
@@ -147,6 +247,10 @@ class LensflareNode extends TempNode {
 
 	}
 
+	/**
+	 * Frees internal resources. This method should be called
+	 * when the effect is no longer required.
+	 */
 	dispose() {
 
 		this._renderTarget.dispose();
@@ -158,4 +262,18 @@ class LensflareNode extends TempNode {
 
 export default LensflareNode;
 
-export const lensflare = ( inputNode, params ) => nodeObject( new LensflareNode( convertToTexture( inputNode ), params ) );
+/**
+ * TSL function for creating a bloom-based lens flare effect.
+ *
+ * @function
+ * @param {TextureNode} node - The node that represents the scene's bloom.
+ * @param {Object} params - The parameter object for configuring the effect.
+ * @param {Node<vec3> | Color} [params.ghostTint=vec3(1, 1, 1)] - Defines the tint of the flare/ghosts.
+ * @param {Node<float> | Number} [params.threshold=float(0.5)] - Controls the size and strength of the effect. A higher threshold results in smaller flares.
+ * @param {Node<float> | Number} [params.ghostSamples=float(4)] - Represents the number of flares/ghosts per bright spot which pivot around the center.
+ * @param {Node<float> | Number} [params.ghostSpacing=float(0.25)] - Defines the spacing of the flares/ghosts.
+ * @param {Node<float> | Number} [params.ghostAttenuationFactor=float(25)] - Defines the attenuation factor of flares/ghosts.
+ * @param {Number} [params.downSampleRatio=4] - Defines how downsampling since the effect is usually not rendered at full resolution.
+ * @returns {LensflareNode}
+ */
+export const lensflare = ( node, params ) => nodeObject( new LensflareNode( convertToTexture( node ), params ) );

+ 329 - 12
examples/jsm/tsl/display/OutlineNode.js

@@ -1,5 +1,7 @@
-import { Color, DepthTexture, FloatType, RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, PostProcessingUtils, NodeUpdateType } from 'three/webgpu';
-import { Loop, int, exp, min, float, mul, uv, vec2, vec3, Fn, textureSize, orthographicDepthToViewZ, screenUV, nodeObject, uniform, vec4, passTexture, texture, perspectiveDepthToViewZ, positionView } from 'three/tsl';
+import { DepthTexture, FloatType, RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, PostProcessingUtils, NodeUpdateType } from 'three/webgpu';
+import { Loop, int, exp, min, float, mul, uv, vec2, vec3, Fn, textureSize, orthographicDepthToViewZ, screenUV, nodeObject, uniform, vec4, passTexture, texture, perspectiveDepthToViewZ, positionView, reference } from 'three/tsl';
+
+/** @module OutlineNode **/
 
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 const _size = /*@__PURE__*/ new Vector2();
@@ -8,6 +10,39 @@ const _BLUR_DIRECTION_Y = /*@__PURE__*/ new Vector2( 0.0, 1.0 );
 
 let _rendererState;
 
+/**
+ * Post processing node for rendering outlines around selected objects. The node
+ * gives you great flexibility in composing the final outline look depending on
+ * your requirements.
+ * ```js
+ * const postProcessing = new THREE.PostProcessing( renderer );
+ *
+ * const scenePass = pass( scene, camera );
+ *
+ * // outline parameter
+ *
+ * const edgeStrength = uniform( 3.0 );
+ * const edgeGlow = uniform( 0.0 );
+ * const edgeThickness = uniform( 1.0 );
+ * const visibleEdgeColor = uniform( new THREE.Color( 0xffffff ) );
+ * const hiddenEdgeColor = uniform( new THREE.Color( 0x4e3636 ) );
+ *
+ * outlinePass = outline( scene, camera, {
+ * 	selectedObjects,
+ * 	edgeGlow,
+ * 	edgeThickness
+ * } );
+ *
+ * // compose custom outline
+ *
+ * const { visibleEdge, hiddenEdge } = outlinePass;
+ * const outlineColor = visibleEdge.mul( visibleEdgeColor ).add( hiddenEdge.mul( hiddenEdgeColor ) ).mul( edgeStrength );
+ *
+ * postProcessing.outputNode = outlineColor.add( scenePass );
+ * ```
+ *
+ * @augments TempNode
+ */
 class OutlineNode extends TempNode {
 
 	static get type() {
@@ -16,6 +51,17 @@ class OutlineNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new outline node.
+	 *
+	 * @param {Scene} scene - A reference to the scene.
+	 * @param {Camera} camera - The camera the scene is rendered with.
+	 * @param {Object} params - The configuration parameters.
+	 * @param {Array<Object3D>} params.selectedObjects - An array of selected objects.
+	 * @param {Node<float>} [params.edgeThickness=float(1)] - The thickness of the edges.
+	 * @param {Node<float>} [params.edgeGlow=float(0)] - Can be used for an animated glow/pulse effects.
+	 * @param {Number} [params.downSampleRatio=2] - The downsample ratio.
+	 */
 	constructor( scene, camera, params = {} ) {
 
 		super( 'vec4' );
@@ -27,101 +73,341 @@ class OutlineNode extends TempNode {
 			downSampleRatio = 2
 		} = params;
 
+		/**
+		 * A reference to the scene.
+		 *
+		 * @type {Scene}
+		 */
 		this.scene = scene;
+
+		/**
+		 * The camera the scene is rendered with.
+		 *
+		 * @type {Camera}
+		 */
 		this.camera = camera;
+
+		/**
+		 * An array of selected objects.
+		 *
+		 * @type {Array<Object3D>}
+		 */
 		this.selectedObjects = selectedObjects;
+
+		/**
+		 * The thickness of the edges.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.edgeThicknessNode = nodeObject( edgeThickness );
+
+		/**
+		 * Can be used for an animated glow/pulse effect.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.edgeGlowNode = nodeObject( edgeGlow );
+
+		/**
+		 * The downsample ratio.
+		 *
+		 * @type {Number}
+		 * @default 2
+		 */
 		this.downSampleRatio = downSampleRatio;
 
+		/**
+		 * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
+		 * its effect once per frame in `updateBefore()`.
+		 *
+		 * @type {String}
+		 * @default 'frame'
+		 */
 		this.updateBeforeType = NodeUpdateType.FRAME;
 
 		// render targets
 
+		/**
+		 * The render target for the depth pre-pass.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTargetDepthBuffer = new RenderTarget();
 		this._renderTargetDepthBuffer.depthTexture = new DepthTexture();
 		this._renderTargetDepthBuffer.depthTexture.type = FloatType;
 
+		/**
+		 * The render target for the mask pass.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTargetMaskBuffer = new RenderTarget();
+
+		/**
+		 * The render target for the mask downsample.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTargetMaskDownSampleBuffer = new RenderTarget( 1, 1, { depthBuffer: false } );
+
+		/**
+		 * The first render target for the edge detection.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTargetEdgeBuffer1 = new RenderTarget( 1, 1, { depthBuffer: false } );
+
+		/**
+		 * The second render target for the edge detection.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTargetEdgeBuffer2 = new RenderTarget( 1, 1, { depthBuffer: false } );
+
+		/**
+		 * The first render target for the blur pass.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTargetBlurBuffer1 = new RenderTarget( 1, 1, { depthBuffer: false } );
+
+		/**
+		 * The second render target for the blur pass.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTargetBlurBuffer2 = new RenderTarget( 1, 1, { depthBuffer: false } );
+
+		/**
+		 * The render target for the final composite.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._renderTargetComposite = new RenderTarget( 1, 1, { depthBuffer: false } );
 
 		// uniforms
 
-		this._cameraNear = uniform( camera.near );
-		this._cameraFar = uniform( camera.far );
+		/**
+		 * Represents the near value of the scene's camera.
+		 *
+		 * @private
+		 * @type {ReferenceNode<float>}
+		 */
+		this._cameraNear = reference( 'near', 'float', camera );
+
+		/**
+		 * Represents the far value of the scene's camera.
+		 *
+		 * @private
+		 * @type {ReferenceNode<float>}
+		 */
+		this._cameraFar = reference( 'far', 'float', camera );
+
+		/**
+		 * Uniform that represents the blur direction of the pass.
+		 *
+		 * @private
+		 * @type {UniformNode<vec2>}
+		 */
 		this._blurDirection = uniform( new Vector2() );
 
+		/**
+		 * Texture node that holds the data from the depth pre-pass.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._depthTextureUniform = texture( this._renderTargetDepthBuffer.depthTexture );
+
+		/**
+		 * Texture node that holds the data from the mask pass.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._maskTextureUniform = texture( this._renderTargetMaskBuffer.texture );
+
+		/**
+		 * Texture node that holds the data from the mask downsample pass.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._maskTextureDownsSampleUniform = texture( this._renderTargetMaskDownSampleBuffer.texture );
+
+		/**
+		 * Texture node that holds the data from the first edge detection pass.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._edge1TextureUniform = texture( this._renderTargetEdgeBuffer1.texture );
+
+		/**
+		 * Texture node that holds the data from the second edge detection pass.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._edge2TextureUniform = texture( this._renderTargetEdgeBuffer2.texture );
+
+		/**
+		 * Texture node that holds the current blurred color data.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._blurColorTextureUniform = texture( this._renderTargetEdgeBuffer1.texture );
 
 		// constants
 
+		/**
+		 * Visible edge color.
+		 *
+		 * @private
+		 * @type {Node<vec3>}
+		 */
 		this._visibleEdgeColor = vec3( 1, 0, 0 );
+
+		/**
+		 * Hidden edge color.
+		 *
+		 * @private
+		 * @type {Node<vec3>}
+		 */
 		this._hiddenEdgeColor = vec3( 0, 1, 0 );
 
 		// materials
 
+		/**
+		 * The material for the depth pre-pass.
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._depthMaterial = new NodeMaterial();
 		this._depthMaterial.fragmentNode = vec4( 0, 0, 0, 1 );
 		this._depthMaterial.name = 'OutlineNode.depth';
 
+		/**
+		 * The material for preparing the mask.
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._prepareMaskMaterial = new NodeMaterial();
 		this._prepareMaskMaterial.name = 'OutlineNode.prepareMask';
 
+		/**
+		 * The copy material
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._materialCopy = new NodeMaterial();
 		this._materialCopy.name = 'OutlineNode.copy';
 
+		/**
+		 * The edge detection material.
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._edgeDetectionMaterial = new NodeMaterial();
 		this._edgeDetectionMaterial.name = 'OutlineNode.edgeDetection';
 
+		/**
+		 * The material that is used to render in the blur pass.
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._separableBlurMaterial = new NodeMaterial();
 		this._separableBlurMaterial.name = 'OutlineNode.separableBlur';
 
+		/**
+		 * The material that is used to render in the blur pass.
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._separableBlurMaterial2 = new NodeMaterial();
 		this._separableBlurMaterial2.name = 'OutlineNode.separableBlur2';
 
+		/**
+		 * The final composite material.
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._compositeMaterial = new NodeMaterial();
 		this._compositeMaterial.name = 'OutlineNode.composite';
 
-		//
-
+		/**
+		 * A set to cache selected objects in the scene.
+		 *
+		 * @private
+		 * @type {Set<Object3D>}
+		 */
 		this._selectionCache = new Set();
-		this._tempPulseColor1 = new Color();
-		this._tempPulseColor2 = new Color();
-
-		//
 
+		/**
+		 * The result of the effect is represented as a separate texture node.
+		 *
+		 * @private
+		 * @type {PassTextureNode}
+		 */
 		this._textureNode = passTexture( this, this._renderTargetComposite.texture );
 
 	}
 
+	/**
+	 * A mask value that represents the visible edge.
+	 *
+	 * @return {Node<float>} The visible edge.
+	 */
 	get visibleEdge() {
 
 		return this.r;
 
 	}
 
+	/**
+	 * A mask value that represents the hidden edge.
+	 *
+	 * @return {Node<float>} The hidden edge.
+	 */
 	get hiddenEdge() {
 
 		return this.g;
 
 	}
 
+	/**
+	 * Returns the result of the effect as a texture node.
+	 *
+	 * @return {PassTextureNode} A texture node that represents the result of the effect.
+	 */
 	getTextureNode() {
 
 		return this._textureNode;
 
 	}
 
+	/**
+	 * Sets the size of the effect.
+	 *
+	 * @param {Number} width - The width of the effect.
+	 * @param {Number} height - The height of the effect.
+	 */
 	setSize( width, height ) {
 
 		this._renderTargetDepthBuffer.setSize( width, height );
@@ -147,6 +433,11 @@ class OutlineNode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to render the effect once per frame.
+	 *
+	 * @param {NodeFrame} frame - The current node frame.
+	 */
 	updateBefore( frame ) {
 
 		const { renderer } = frame;
@@ -259,6 +550,12 @@ class OutlineNode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to setup the effect's TSL code.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {PassTextureNode}
+	 */
 	setup() {
 
 		// prepare mask material
@@ -387,6 +684,10 @@ class OutlineNode extends TempNode {
 
 	}
 
+	/**
+	 * Frees internal resources. This method should be called
+	 * when the effect is no longer required.
+	 */
 	dispose() {
 
 		this.selectedObjects.length = 0;
@@ -410,8 +711,11 @@ class OutlineNode extends TempNode {
 
 	}
 
-	//
-
+	/**
+	 * Updates the selection cache based on the selected objects.
+	 *
+	 * @private
+	 */
 	_updateSelectionCache() {
 
 		for ( let i = 0; i < this.selectedObjects.length; i ++ ) {
@@ -431,4 +735,17 @@ class OutlineNode extends TempNode {
 
 export default OutlineNode;
 
+/**
+ * TSL function for creating an outline effect around selected objects.
+ *
+ * @function
+ * @param {Scene} scene - A reference to the scene.
+ * @param {Camera} camera - The camera the scene is rendered with.
+ * @param {Object} params - The configuration parameters.
+ * @param {Array<Object3D>} params.selectedObjects - An array of selected objects.
+ * @param {Node<float>} [params.edgeThickness=float(1)] - The thickness of the edges.
+ * @param {Node<float>} [params.edgeGlow=float(0)] - Can be used for animated glow/pulse effects.
+ * @param {Number} [params.downSampleRatio=2] - The downsample ratio.
+ * @returns {OutlineNode}
+ */
 export const outline = ( scene, camera, params ) => nodeObject( new OutlineNode( scene, camera, params ) );

+ 1 - 1
examples/jsm/tsl/display/SSAAPassNode.js

@@ -14,7 +14,7 @@ let _rendererState;
  * This node produces a high-quality anti-aliased output but is also extremely expensive because of
  * its brute-force approach of re-rendering the entire scene multiple times.
  *
- * References: https://en.wikipedia.org/wiki/Supersampling
+ * Reference: {@link https://en.wikipedia.org/wiki/Supersampling}
  *
  * @augments PassNode
  */

+ 187 - 14
examples/jsm/tsl/display/SSRNode.js

@@ -1,13 +1,18 @@
 import { NearestFilter, RenderTarget, Vector2, PostProcessingUtils, QuadMesh, TempNode, NodeMaterial, NodeUpdateType } from 'three/webgpu';
 import { reference, viewZToPerspectiveDepth, logarithmicDepthToViewZ, getScreenPosition, getViewPosition, sqrt, mul, div, cross, float, Continue, Break, Loop, int, max, abs, sub, If, dot, reflect, normalize, screenCoordinate, nodeObject, Fn, passTexture, uv, uniform, perspectiveDepthToViewZ, orthographicDepthToViewZ, vec2, vec3, vec4 } from 'three/tsl';
 
+/** @module SSRNode **/
+
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 const _size = /*@__PURE__*/ new Vector2();
 let _rendererState;
 
 /**
- * References:
- * https://lettier.github.io/3d-game-shaders-for-beginners/screen-space-reflection.html
+ * Post processing node for computing screen space reflections (SSR).
+ *
+ * Reference: {@link https://lettier.github.io/3d-game-shaders-for-beginners/screen-space-reflection.html}
+ *
+ * @augments TempNode
  */
 class SSRNode extends TempNode {
 
@@ -17,56 +22,198 @@ class SSRNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new SSR node.
+	 *
+	 * @param {Node<vec4>} colorNode - The node that represents the beauty pass.
+	 * @param {Node<float>} depthNode - A node that represents the beauty pass's depth.
+	 * @param {Node<vec3>} normalNode - A node that represents the beauty pass's normals.
+	 * @param {Node<float>} metalnessNode - A node that represents the beauty pass's metalness.
+	 * @param {Camera} camera - The camera the scene is rendered with.
+	 */
 	constructor( colorNode, depthNode, normalNode, metalnessNode, camera ) {
 
 		super( 'vec4' );
 
+		/**
+		 * The node that represents the beauty pass.
+		 *
+		 * @type {Node<vec4>}
+		 */
 		this.colorNode = colorNode;
+
+		/**
+		 * A node that represents the beauty pass's depth.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.depthNode = depthNode;
+
+		/**
+		 * A node that represents the beauty pass's normals.
+		 *
+		 * @type {Node<vec3>}
+		 */
 		this.normalNode = normalNode;
+
+		/**
+		 * A node that represents the beauty pass's metalness.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.metalnessNode = metalnessNode;
+
+		/**
+		 * The camera the scene is rendered with.
+		 *
+		 * @type {Camera}
+		 */
 		this.camera = camera;
 
+		/**
+		 * The resolution scale. By default SSR reflections
+		 * are computed in half resolutions. Setting the value
+		 * to `1` improves quality but also results in more
+		 * computational overhead.
+		 *
+		 * @type {Number}
+		 * @default
+		 */
 		this.resolutionScale = 0.5;
 
+		/**
+		 * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
+		 * its effect once per frame in `updateBefore()`.
+		 *
+		 * @type {String}
+		 * @default 'frame'
+		 */
 		this.updateBeforeType = NodeUpdateType.FRAME;
 
-		// render targets
-
+		/**
+		 * The render target the SSR is rendered into.
+		 *
+		 * @private
+		 * @type {RenderTarget}
+		 */
 		this._ssrRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, minFilter: NearestFilter, magFilter: NearestFilter } );
 		this._ssrRenderTarget.texture.name = 'SSRNode.SSR';
 
-		// uniforms
-
-		this.maxDistance = uniform( 1 ); // controls how far a fragment can reflect
-		this.thickness = uniform( 0.1 ); // controls the cutoff between what counts as a possible reflection hit and what does not
-		this.opacity = uniform( 1 ); // controls the transparency of the reflected colors
-
+		/**
+		 * Controls how far a fragment can reflect
+		 *
+		 *
+		 * @type {UniformNode<float>}
+		 */
+		this.maxDistance = uniform( 1 );
+
+		/**
+		 * Controls the cutoff between what counts as a possible reflection hit and what does not.
+		 *
+		 * @type {UniformNode<float>}
+		 */
+		this.thickness = uniform( 0.1 );
+
+		/**
+		 * Controls the transparency of the reflected colors.
+		 *
+		 * @type {UniformNode<float>}
+		 */
+		this.opacity = uniform( 1 );
+
+		/**
+		 * Represents the projection matrix of the scene's camera.
+		 *
+		 * @private
+		 * @type {UniformNode<mat4>}
+		 */
 		this._cameraProjectionMatrix = uniform( camera.projectionMatrix );
+
+		/**
+		 * Represents the inverse projection matrix of the scene's camera.
+		 *
+		 * @private
+		 * @type {UniformNode<mat4>}
+		 */
 		this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
+
+		/**
+		 * Represents the near value of the scene's camera.
+		 *
+		 * @private
+		 * @type {ReferenceNode<float>}
+		 */
 		this._cameraNear = reference( 'near', 'float', camera );
+
+		/**
+		 * Represents the far value of the scene's camera.
+		 *
+		 * @private
+		 * @type {ReferenceNode<float>}
+		 */
 		this._cameraFar = reference( 'far', 'float', camera );
+
+		/**
+		 * Whether the scene's camera is perspective or orthographic.
+		 *
+		 * @private
+		 * @type {UniformNode<bool>}
+		 */
 		this._isPerspectiveCamera = uniform( camera.isPerspectiveCamera ? 1 : 0 );
+
+		/**
+		 * The resolution of the pass.
+		 *
+		 * @private
+		 * @type {UniformNode<vec2>}
+		 */
 		this._resolution = uniform( new Vector2() );
-		this._maxStep = uniform( 0 );
 
-		// materials
+		/**
+		 * This value is derived from the resolution and restricts
+		 * the maximum raymarching steps in the fragment shader.
+		 *
+		 * @private
+		 * @type {UniformNode<float>}
+		 */
+		this._maxStep = uniform( 0 );
 
+		/**
+		 * The material that is used to render the effect.
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._material = new NodeMaterial();
 		this._material.name = 'SSRNode.SSR';
 
-		//
-
+		/**
+		 * The result of the effect is represented as a separate texture node.
+		 *
+		 * @private
+		 * @type {PassTextureNode}
+		 */
 		this._textureNode = passTexture( this, this._ssrRenderTarget.texture );
 
 	}
 
+	/**
+	 * Returns the result of the effect as a texture node.
+	 *
+	 * @return {PassTextureNode} A texture node that represents the result of the effect.
+	 */
 	getTextureNode() {
 
 		return this._textureNode;
 
 	}
 
+	/**
+	 * Sets the size of the effect.
+	 *
+	 * @param {Number} width - The width of the effect.
+	 * @param {Number} height - The height of the effect.
+	 */
 	setSize( width, height ) {
 
 		width = Math.round( this.resolutionScale * width );
@@ -79,6 +226,11 @@ class SSRNode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to render the effect once per frame.
+	 *
+	 * @param {NodeFrame} frame - The current node frame.
+	 */
 	updateBefore( frame ) {
 
 		const { renderer } = frame;
@@ -107,6 +259,12 @@ class SSRNode extends TempNode {
 
 	}
 
+	/**
+	 * This method is used to setup the effect's TSL code.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {PassTextureNode}
+	 */
 	setup( builder ) {
 
 		const uvNode = uv();
@@ -351,6 +509,10 @@ class SSRNode extends TempNode {
 
 	}
 
+	/**
+	 * Frees internal resources. This method should be called
+	 * when the effect is no longer required.
+	 */
 	dispose() {
 
 		this._ssrRenderTarget.dispose();
@@ -363,4 +525,15 @@ class SSRNode extends TempNode {
 
 export default SSRNode;
 
+/**
+ * TSL function for creating screen space reflections (SSR).
+ *
+ * @function
+ * @param {Node<vec4>} colorNode - The node that represents the beauty pass.
+ * @param {Node<float>} depthNode - A node that represents the beauty pass's depth.
+ * @param {Node<vec3>} normalNode - A node that represents the beauty pass's normals.
+ * @param {Node<float>} metalnessNode - A node that represents the beauty pass's metalness.
+ * @param {Camera} camera - The camera the scene is rendered with.
+ * @returns {SSRNode}
+ */
 export const ssr = ( colorNode, depthNode, normalNode, metalnessNode, camera ) => nodeObject( new SSRNode( nodeObject( colorNode ), nodeObject( depthNode ), nodeObject( normalNode ), nodeObject( metalnessNode ), camera ) );

+ 108 - 13
examples/jsm/tsl/display/TRAAPassNode.js

@@ -1,19 +1,25 @@
 import { Color, Vector2, NearestFilter, Matrix4, PostProcessingUtils, PassNode, QuadMesh, NodeMaterial } from 'three/webgpu';
 import { add, float, If, Loop, int, Fn, min, max, clamp, nodeObject, texture, uniform, uv, vec2, vec4, luminance } from 'three/tsl';
 
+/** @module TRAAPassNode **/
+
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 const _size = /*@__PURE__*/ new Vector2();
 
 let _rendererState;
 
+
 /**
-* Temporal Reprojection Anti-Aliasing (TRAA).
-*
-* References:
-* https://alextardif.com/TAA.html
-* https://www.elopezr.com/temporal-aa-and-the-quest-for-the-holy-trail/
-*
-*/
+ * A special render pass node that renders the scene with TRAA (Temporal Reprojection Anti-Aliasing).
+ *
+ * Note: The current implementation does not yet support MRT setups.
+ *
+ * References:
+ * - {@link https://alextardif.com/TAA.html}
+ * - {@link https://www.elopezr.com/temporal-aa-and-the-quest-for-the-holy-trail/}
+ *
+ * @augments PassNode
+ */
 class TRAAPassNode extends PassNode {
 
 	static get type() {
@@ -22,34 +28,100 @@ class TRAAPassNode extends PassNode {
 
 	}
 
+	/**
+	 * Constructs a new TRAA pass node.
+	 *
+	 * @param {Scene} scene - The scene to render.
+	 * @param {Camera} camera - The camera to render the scene with.
+	 */
 	constructor( scene, camera ) {
 
 		super( PassNode.COLOR, scene, camera );
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isTRAAPassNode = true;
 
+		/**
+		 * The clear color of the pass.
+		 *
+		 * @type {Color}
+		 * @default 0x000000
+		 */
 		this.clearColor = new Color( 0x000000 );
+
+		/**
+		 * The clear alpha of the pass.
+		 *
+		 * @type {Number}
+		 * @default 0
+		 */
 		this.clearAlpha = 0;
 
+		/**
+		 * The jitter index selects the current camera offset value.
+		 *
+		 * @private
+		 * @type {Number}
+		 * @default 0
+		 */
 		this._jitterIndex = 0;
-		this._originalProjectionMatrix = new Matrix4();
 
-		// uniforms
+		/**
+		 * Used to save the original/unjittered projection matrix.
+		 *
+		 * @private
+		 * @type {Matrix4}
+		 */
+		this._originalProjectionMatrix = new Matrix4();
 
+		/**
+		 * A uniform node holding the inverse resolution value.
+		 *
+		 * @private
+		 * @type {UniformNode<vec2>}
+		 */
 		this._invSize = uniform( new Vector2() );
 
-		// render targets
-
+		/**
+		 * The render target that holds the current sample.
+		 *
+		 * @private
+		 * @type {RenderTarget?}
+		 */
 		this._sampleRenderTarget = null;
-		this._historyRenderTarget = null;
 
-		// materials
+		/**
+		 * The render target that represents the history of frame data.
+		 *
+		 * @private
+		 * @type {RenderTarget?}
+		 */
+		this._historyRenderTarget = null;
 
+		/**
+		 * Material used for the resolve step.
+		 *
+		 * @private
+		 * @type {NodeMaterial}
+		 */
 		this._resolveMaterial = new NodeMaterial();
 		this._resolveMaterial.name = 'TRAA.Resolve';
 
 	}
 
+	/**
+	 * Sets the size of the effect.
+	 *
+	 * @param {Number} width - The width of the effect.
+	 * @param {Number} height - The height of the effect.
+	 * @return {Boolean} Whether the TRAA needs a restart or not. That is required after a resize since buffer data with different sizes can't be resolved.
+	 */
 	setSize( width, height ) {
 
 		super.setSize( width, height );
@@ -71,6 +143,11 @@ class TRAAPassNode extends PassNode {
 
 	}
 
+	/**
+	 * This method is used to render the effect once per frame.
+	 *
+	 * @param {NodeFrame} frame - The current node frame.
+	 */
 	updateBefore( frame ) {
 
 		const { renderer } = frame;
@@ -218,6 +295,12 @@ class TRAAPassNode extends PassNode {
 
 	}
 
+	/**
+	 * This method is used to setup the effect's render targets and TSL code.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {PassTextureNode}
+	 */
 	setup( builder ) {
 
 		if ( this._sampleRenderTarget === null ) {
@@ -317,6 +400,10 @@ class TRAAPassNode extends PassNode {
 
 	}
 
+	/**
+	 * Frees internal resources. This method should be called
+	 * when the effect is no longer required.
+	 */
 	dispose() {
 
 		super.dispose();
@@ -352,4 +439,12 @@ const _JitterVectors = [
 	[ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]
 ];
 
+/**
+ * TSL function for creating a TRAA pass node for Temporal Reprojection Anti-Aliasing.
+ *
+ * @function
+ * @param {Scene} scene - The scene to render.
+ * @param {Camera} camera - The camera to render the scene with.
+ * @returns {TRAAPassNode}
+ */
 export const traaPass = ( scene, camera ) => nodeObject( new TRAAPassNode( scene, camera ) );

粤ICP备19079148号