Prechádzať zdrojové kódy

Node: Document more modules. (#30067)

Michael Herzog 1 rok pred
rodič
commit
19bdc3a100

+ 21 - 21
src/nodes/display/ColorAdjustment.js

@@ -11,8 +11,8 @@ import { LinearSRGBColorSpace } from '../../constants.js';
  * Computes a grayscale value for the given RGB color value.
  *
  * @method
- * @param {vec3} color - The color value to compute the grayscale for.
- * @return {vec3} The grayscale color.
+ * @param {Node<vec3>} color - The color value to compute the grayscale for.
+ * @return {Node<vec3>} The grayscale color.
  */
 export const grayscale = /*@__PURE__*/ Fn( ( [ color ] ) => {
 
@@ -24,9 +24,9 @@ export const grayscale = /*@__PURE__*/ Fn( ( [ color ] ) => {
  * Super-saturates or desaturates the given RGB color.
  *
  * @method
- * @param {vec3} color - The input color.
- * @param {float} [adjustment=1] - Specifies the amount of the conversion. A value under `1` desaturates the color, a value over `1` super-saturates it.
- * @return {vec3} The saturated color.
+ * @param {Node<vec3>} color - The input color.
+ * @param {Node<float>} [adjustment=1] - Specifies the amount of the conversion. A value under `1` desaturates the color, a value over `1` super-saturates it.
+ * @return {Node<vec3>} The saturated color.
  */
 export const saturation = /*@__PURE__*/ Fn( ( [ color, adjustment = float( 1 ) ] ) => {
 
@@ -40,9 +40,9 @@ export const saturation = /*@__PURE__*/ Fn( ( [ color, adjustment = float( 1 ) ]
  * compared to {@link ColorAdjustment#saturation}.
  *
  * @method
- * @param {vec3} color - The input color.
- * @param {float} [adjustment=1] - Controls the intensity of the vibrance effect.
- * @return {vec3} The updated color.
+ * @param {Node<vec3>} color - The input color.
+ * @param {Node<float>} [adjustment=1] - Controls the intensity of the vibrance effect.
+ * @return {Node<vec3>} The updated color.
  */
 export const vibrance = /*@__PURE__*/ Fn( ( [ color, adjustment = float( 1 ) ] ) => {
 
@@ -59,9 +59,9 @@ export const vibrance = /*@__PURE__*/ Fn( ( [ color, adjustment = float( 1 ) ] )
  * Updates the hue component of the given RGB color while preserving its luminance and saturation.
  *
  * @method
- * @param {vec3} color - The input color.
- * @param {float} [adjustment=1] - Defines the degree of hue rotation in radians. A positive value rotates the hue clockwise, while a negative value rotates it counterclockwise.
- * @return {vec3} The updated color.
+ * @param {Node<vec3>} color - The input color.
+ * @param {Node<float>} [adjustment=1] - Defines the degree of hue rotation in radians. A positive value rotates the hue clockwise, while a negative value rotates it counterclockwise.
+ * @return {Node<vec3>} The updated color.
  */
 export const hue = /*@__PURE__*/ Fn( ( [ color, adjustment = float( 1 ) ] ) => {
 
@@ -77,9 +77,9 @@ export const hue = /*@__PURE__*/ Fn( ( [ color, adjustment = float( 1 ) ] ) => {
  * Computes the luminance for the given RGB color value.
  *
  * @method
- * @param {vec3} color - The color value to compute the luminance for.
- * @param {vec3?} luminanceCoefficients - The luminance coefficients. By default predefined values of the current working color space are used.
- * @return {vec3} The luminance.
+ * @param {Node<vec3>} color - The color value to compute the luminance for.
+ * @param {Node<vec3>?} luminanceCoefficients - The luminance coefficients. By default predefined values of the current working color space are used.
+ * @return {Node<vec3>} The luminance.
  */
 export const luminance = (
 	color,
@@ -94,13 +94,13 @@ export const luminance = (
  * or AgX Log), and will return output in the same space. Output may require clamping >=0.
  *
  * @method
- * @param {vec4} color Input (-Infinity < input < +Infinity)
- * @param {number | vec3} slope Slope (0 ≤ slope < +Infinity)
- * @param {number | vec3} offset Offset (-Infinity < offset < +Infinity; typically -1 < offset < 1)
- * @param {number | vec3} power Power (0 < power < +Infinity)
- * @param {number} saturation Saturation (0 ≤ saturation < +Infinity; typically 0 ≤ saturation < 4)
- * @param {vec3} luminanceCoefficients Luminance coefficients for saturation term, typically Rec. 709
- * @return Output, -Infinity < output < +Infinity
+ * @param {Node<vec4>} color Input (-Infinity < input < +Infinity)
+ * @param {Node<vec3>} slope Slope (0 ≤ slope < +Infinity)
+ * @param {Node<vec3>} offset Offset (-Infinity < offset < +Infinity; typically -1 < offset < 1)
+ * @param {Node<vec3>} power Power (0 < power < +Infinity)
+ * @param {Node<float>} saturation Saturation (0 ≤ saturation < +Infinity; typically 0 ≤ saturation < 4)
+ * @param {Node<vec3>} luminanceCoefficients Luminance coefficients for saturation term, typically Rec. 709
+ * @return {Node<vec4>} Output, -Infinity < output < +Infinity
  *
  * References:
  * - ASC CDL v1.2

+ 4 - 4
src/nodes/display/ColorSpaceFunctions.js

@@ -7,8 +7,8 @@ import { Fn } from '../tsl/TSLCore.js';
  * Converts the given color value from sRGB to linear-sRGB color space.
  *
  * @method
- * @param {vec3} color - The sRGB color.
- * @return {vec3} The linear-sRGB color.
+ * @param {Node<vec3>} color - The sRGB color.
+ * @return {Node<vec3>} The linear-sRGB color.
  */
 export const sRGBTransferEOTF = /*@__PURE__*/ Fn( ( [ color ] ) => {
 
@@ -32,8 +32,8 @@ export const sRGBTransferEOTF = /*@__PURE__*/ Fn( ( [ color ] ) => {
  * Converts the given color value from linear-sRGB to sRGB color space.
  *
  * @method
- * @param {vec3} color - The linear-sRGB color.
- * @return {vec3} The sRGB color.
+ * @param {Node<vec3>} color - The linear-sRGB color.
+ * @return {Node<vec3>} The sRGB color.
  */
 export const sRGBTransferOETF = /*@__PURE__*/ Fn( ( [ color ] ) => {
 

+ 18 - 18
src/nodes/display/ToneMappingFunctions.js

@@ -9,9 +9,9 @@ import { mul, sub, div } from '../math/OperatorNode.js';
  * Linear tone mapping, exposure only.
  *
  * @method
- * @param {vec3} color - The color that should be tone mapped.
- * @param {float} exposure - The exposure.
- * @return {vec3} The tone mapped color.
+ * @param {Node<vec3>} color - The color that should be tone mapped.
+ * @param {Node<float>} exposure - The exposure.
+ * @return {Node<vec3>} The tone mapped color.
  */
 export const linearToneMapping = /*@__PURE__*/ Fn( ( [ color, exposure ] ) => {
 
@@ -32,9 +32,9 @@ export const linearToneMapping = /*@__PURE__*/ Fn( ( [ color, exposure ] ) => {
  * Reference: {@link https://www.cs.utah.edu/docs/techreports/2002/pdf/UUCS-02-001.pdf}
  *
  * @method
- * @param {vec3} color - The color that should be tone mapped.
- * @param {float} exposure - The exposure.
- * @return {vec3} The tone mapped color.
+ * @param {Node<vec3>} color - The color that should be tone mapped.
+ * @param {Node<float>} exposure - The exposure.
+ * @return {Node<vec3>} The tone mapped color.
  */
 export const reinhardToneMapping = /*@__PURE__*/ Fn( ( [ color, exposure ] ) => {
 
@@ -57,9 +57,9 @@ export const reinhardToneMapping = /*@__PURE__*/ Fn( ( [ color, exposure ] ) =>
  * Reference: {@link http://filmicworlds.com/blog/filmic-tonemapping-operators/}
  *
  * @method
- * @param {vec3} color - The color that should be tone mapped.
- * @param {float} exposure - The exposure.
- * @return {vec3} The tone mapped color.
+ * @param {Node<vec3>} color - The color that should be tone mapped.
+ * @param {Node<float>} exposure - The exposure.
+ * @return {Node<vec3>} The tone mapped color.
  */
 export const cineonToneMapping = /*@__PURE__*/ Fn( ( [ color, exposure ] ) => {
 
@@ -98,9 +98,9 @@ const RRTAndODTFit = /*@__PURE__*/ Fn( ( [ color ] ) => {
  * Reference: {@link https://github.com/selfshadow/ltc_code/blob/master/webgl/shaders/ltc/ltc_blit.fs}
  *
  * @method
- * @param {vec3} color - The color that should be tone mapped.
- * @param {float} exposure - The exposure.
- * @return {vec3} The tone mapped color.
+ * @param {Node<vec3>} color - The color that should be tone mapped.
+ * @param {Node<float>} exposure - The exposure.
+ * @return {Node<vec3>} The tone mapped color.
  */
 export const acesFilmicToneMapping = /*@__PURE__*/ Fn( ( [ color, exposure ] ) => {
 
@@ -156,9 +156,9 @@ const agxDefaultContrastApprox = /*@__PURE__*/ Fn( ( [ x_immutable ] ) => {
  * AgX tone mapping.
  *
  * @method
- * @param {vec3} color - The color that should be tone mapped.
- * @param {float} exposure - The exposure.
- * @return {vec3} The tone mapped color.
+ * @param {Node<vec3>} color - The color that should be tone mapped.
+ * @param {Node<float>} exposure - The exposure.
+ * @return {Node<vec3>} The tone mapped color.
  */
 export const agxToneMapping = /*@__PURE__*/ Fn( ( [ color, exposure ] ) => {
 
@@ -197,9 +197,9 @@ export const agxToneMapping = /*@__PURE__*/ Fn( ( [ color, exposure ] ) => {
  * Reference: {@link https://modelviewer.dev/examples/tone-mapping}
  *
  * @method
- * @param {vec3} color - The color that should be tone mapped.
- * @param {float} exposure - The exposure.
- * @return {vec3} The tone mapped color.
+ * @param {Node<vec3>} color - The color that should be tone mapped.
+ * @param {Node<float>} exposure - The exposure.
+ * @return {Node<vec3>} The tone mapped color.
  */
 export const neutralToneMapping = /*@__PURE__*/ Fn( ( [ color, exposure ] ) => {
 

+ 43 - 2
src/nodes/geometry/RangeNode.js

@@ -12,6 +12,17 @@ import { InstancedBufferAttribute } from '../../core/InstancedBufferAttribute.js
 let min = null;
 let max = null;
 
+/**
+ * `RangeNode` generates random instanced attribute data in a defined range.
+ * An exemplary use case for this utility node is to generate random per-instance
+ * colors:
+ * ```js
+ * const material = new MeshBasicNodeMaterial();
+ * material.colorNode = range( new Color( 0x000000 ), new Color( 0xFFFFFF ) );
+ * const mesh = new InstancedMesh( geometry, material, count );
+ * ```
+ * @augments Node
+ */
 class RangeNode extends Node {
 
 	static get type() {
@@ -20,15 +31,39 @@ class RangeNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a new range node.
+	 *
+	 * @param {Node<any>} [minNode=float()] - A node defining the lower bound of the range.
+	 * @param {Node<any>} [maxNode=float()] - A node defining the upper bound of the range.
+	 */
 	constructor( minNode = float(), maxNode = float() ) {
 
 		super();
 
+		/**
+		 *  A node defining the lower bound of the range.
+		 *
+		 * @type {Node<any>}
+		 * @default float()
+		 */
 		this.minNode = minNode;
+
+		/**
+		 *  A node defining the upper bound of the range.
+		 *
+		 * @type {Node<any>}
+		 * @default float()
+		 */
 		this.maxNode = maxNode;
 
 	}
 
+	/**
+	 * Returns the vector length which is computed based on the range definition.
+	 *
+	 * @return {Number} The vector length.
+	 */
 	getVectorLength( builder ) {
 
 		const minLength = builder.getTypeLength( getValueType( this.minNode.value ) );
@@ -38,6 +73,12 @@ class RangeNode extends Node {
 
 	}
 
+	/**
+	 * This method is overwritten since the node type is inferred from range definition.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The node type.
+	 */
 	getNodeType( builder ) {
 
 		return builder.object.count > 1 ? builder.getTypeFromLength( this.getVectorLength( builder ) ) : 'float';
@@ -65,11 +106,11 @@ class RangeNode extends Node {
 			max.setScalar( 0 );
 
 			if ( minLength === 1 ) min.setScalar( minValue );
-			else if ( minValue.isColor ) min.set( minValue.r, minValue.g, minValue.b );
+			else if ( minValue.isColor ) min.set( minValue.r, minValue.g, minValue.b, 1 );
 			else min.set( minValue.x, minValue.y, minValue.z || 0, minValue.w || 0 );
 
 			if ( maxLength === 1 ) max.setScalar( maxValue );
-			else if ( maxValue.isColor ) max.set( maxValue.r, maxValue.g, maxValue.b );
+			else if ( maxValue.isColor ) max.set( maxValue.r, maxValue.g, maxValue.b, 1 );
 			else max.set( maxValue.x, maxValue.y, maxValue.z || 0, maxValue.w || 0 );
 
 			const stride = 4;

+ 43 - 0
src/nodes/math/ConditionalNode.js

@@ -2,6 +2,19 @@ import Node from '../core/Node.js';
 import { property } from '../core/PropertyNode.js';
 import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js';
 
+/**
+ * Represents a logical `if/else` statement. Can be used as an alternative
+ * to the `If()`/`Else()` syntax.
+ *
+ * The corresponding TSL `select()` looks like so:
+ * ```js
+ * velocity = position.greaterThanEqual( limit ).select( velocity.negate(), velocity );
+ * ```
+ * The `select()` method is called in a chaining fashion on a codition. The parameter nodes of `select()`
+ * determine the outcome of the entire statement.
+ *
+ * @augments Node
+ */
 class ConditionalNode extends Node {
 
 	static get type() {
@@ -10,17 +23,47 @@ class ConditionalNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a new conditional node.
+	 *
+	 * @param {Node} condNode - The node that defines the condition.
+	 * @param {Node} ifNode - The node that is evaluate when the condition ends up `true`.
+	 * @param {Node?} [elseNode=null] - The node that is evaluate when the condition ends up `false`.
+	 */
 	constructor( condNode, ifNode, elseNode = null ) {
 
 		super();
 
+		/**
+		 * The node that defines the condition.
+		 *
+		 * @type {Node}
+		 */
 		this.condNode = condNode;
 
+		/**
+		 * The node that is evaluate when the condition ends up `true`.
+		 *
+		 * @type {Node}
+		 */
 		this.ifNode = ifNode;
+
+		/**
+		 * The node that is evaluate when the condition ends up `false`.
+		 *
+		 * @type {Node}
+		 */
 		this.elseNode = elseNode;
 
 	}
 
+	/**
+	 * This method is overwritten since the node type is inferred from the if/else
+	 * nodes.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The node type.
+	 */
 	getNodeType( builder ) {
 
 		const ifType = this.ifNode.getNodeType( builder );

+ 9 - 0
src/nodes/math/Hash.js

@@ -1,5 +1,14 @@
 import { Fn } from '../tsl/TSLBase.js';
 
+/** @module Hash **/
+
+/**
+ * Generates a hash value in the range `[0, 1]` from the given seed.
+ *
+ * @method
+ * @param {Node<float>} seed - The seed.
+ * @return {Node<float>} The hash value.
+ */
 export const hash = /*@__PURE__*/ Fn( ( [ seed ] ) => {
 
 	// Taken from https://www.shadertoy.com/view/XlGcRh, originally from pcg-random.org

+ 56 - 0
src/nodes/math/MathNode.js

@@ -2,6 +2,16 @@ import TempNode from '../core/TempNode.js';
 import { sub, mul, div } from './OperatorNode.js';
 import { addMethodChaining, nodeObject, nodeProxy, float, vec2, vec3, vec4, Fn } from '../tsl/TSLCore.js';
 
+/**
+ * This node represents a variety of mathematical methods available in shaders.
+ * They are divided into three categories:
+ *
+ * - Methods with one input like `sin`, `cos` or `normalize`.
+ * - Methods with two inputs like `dot`, `cross` or `pow`.
+ * - Methods with three inputs like `mix`, `clamp` or `smoothstep`.
+ *
+ * @augments TempNode
+ */
 class MathNode extends TempNode {
 
 	static get type() {
@@ -10,18 +20,58 @@ class MathNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new math node.
+	 *
+	 * @param {String} method - The method name.
+	 * @param {Node} aNode - The first input.
+	 * @param {Node?} [bNode=null] - The second input.
+	 * @param {Node?} [cNode=null] - The third input.
+	 */
 	constructor( method, aNode, bNode = null, cNode = null ) {
 
 		super();
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.method = method;
 
+		/**
+		 * The first input.
+		 *
+		 * @type {Node}
+		 */
 		this.aNode = aNode;
+
+		/**
+		 * The second input.
+		 *
+		 * @type {Node?}
+		 * @default null
+		 */
 		this.bNode = bNode;
+
+		/**
+		 * The third input.
+		 *
+		 * @type {Node?}
+		 * @default null
+		 */
 		this.cNode = cNode;
 
 	}
 
+	/**
+	 * The input type is inferred from the node types of the input nodes.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The input type.
+	 */
 	getInputType( builder ) {
 
 		const aType = this.aNode.getNodeType( builder );
@@ -50,6 +100,12 @@ class MathNode extends TempNode {
 
 	}
 
+	/**
+	 * The selected method as well as the input type determine the node type of this node.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The node type.
+	 */
 	getNodeType( builder ) {
 
 		const method = this.method;

+ 45 - 1
src/nodes/math/MathUtils.js

@@ -1,8 +1,52 @@
 import { sub, mul, div, add } from './OperatorNode.js';
 import { PI, pow, sin } from './MathNode.js';
 
-// remapping functions https://iquilezles.org/articles/functions/
+/** @module MathUtils **/
+
+/**
+ * A function that remaps the `[0,1]` interval into the `[0,1]` interval.
+ * The corners are mapped to `0` and the center to `1`.
+ * Reference: {@link https://iquilezles.org/articles/functions/}.
+ *
+ * @method
+ * @param {Node<float>} x - The value to remap.
+ * @param {Node<float>} k - Allows to control the remapping functions shape by rising the parabolar to a power `k`.
+ * @return {Node<float>} The remapped value.
+ */
 export const parabola = ( x, k ) => pow( mul( 4.0, x.mul( sub( 1.0, x ) ) ), k );
+
+/**
+ * A function that remaps the `[0,1]` interval into the `[0,1]` interval.
+ * Expands the sides and compresses the center, and keeps `0.5` mapped to `0.5`.
+ * Reference: {@link https://iquilezles.org/articles/functions/}.
+ *
+ * @method
+ * @param {Node<float>} x - The value to remap.
+ * @param {Node<float>} k - `k=1` is the identity curve,`k<1` produces the classic `gain()` shape, and `k>1` produces "s" shaped curces.
+ * @return {Node<float>} The remapped value.
+ */
 export const gain = ( x, k ) => x.lessThan( 0.5 ) ? parabola( x.mul( 2.0 ), k ).div( 2.0 ) : sub( 1.0, parabola( mul( sub( 1.0, x ), 2.0 ), k ).div( 2.0 ) );
+
+/**
+ * A function that remaps the `[0,1]` interval into the `[0,1]` interval.
+ * A generalization of the `parabola()`. Keeps the corners mapped to 0 but allows the control of the shape one either side of the curve.
+ * Reference: {@link https://iquilezles.org/articles/functions/}.
+ *
+ * @method
+ * @param {Node<float>} x - The value to remap.
+ * @param {Node<float>} a - First control paramter.
+ * @param {Node<float>} b - Second control paramter.
+ * @return {Node<float>} The remapped value.
+ */
 export const pcurve = ( x, a, b ) => pow( div( pow( x, a ), add( pow( x, a ), pow( sub( 1.0, x ), b ) ) ), 1.0 / a );
+
+/**
+ * A phase shifted sinus curve that starts at zero and ends at zero, with bouncing behavior.
+ * Reference: {@link https://iquilezles.org/articles/functions/}.
+ *
+ * @method
+ * @param {Node<float>} x - The value to compute the sin for.
+ * @param {Node<float>} k - Controls the amount of bounces.
+ * @return {Node<float>} The result value.
+ */
 export const sinc = ( x, k ) => sin( PI.mul( k.mul( x ).sub( 1.0 ) ) ).div( PI.mul( k.mul( x ).sub( 1.0 ) ) );

+ 39 - 0
src/nodes/math/OperatorNode.js

@@ -1,6 +1,12 @@
 import TempNode from '../core/TempNode.js';
 import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js';
 
+/**
+ * This node represents basic mathematical and logical operations like addition,
+ * subtraction or comparisons (e.g. `equal()`).
+ *
+ * @augments TempNode
+ */
 class OperatorNode extends TempNode {
 
 	static get type() {
@@ -9,6 +15,14 @@ class OperatorNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new operator node.
+	 *
+	 * @param {String} op - The operator.
+	 * @param {Node} aNode - The first input.
+	 * @param {Node} bNode - The second input.
+	 * @param {...Node} params - Additional input parameters.
+	 */
 	constructor( op, aNode, bNode, ...params ) {
 
 		super();
@@ -28,12 +42,37 @@ class OperatorNode extends TempNode {
 
 		}
 
+		/**
+		 * The operator.
+		 *
+		 * @type {String}
+		 */
 		this.op = op;
+
+		/**
+		 * The first input.
+		 *
+		 * @type {Node}
+		 */
 		this.aNode = aNode;
+
+		/**
+		 * The second input.
+		 *
+		 * @type {Node}
+		 */
 		this.bNode = bNode;
 
 	}
 
+	/**
+	 * This method is overwritten since the node type is inferred from the operator
+	 * and the input node types.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @param {String} output - The current output string.
+	 * @return {String} The node type.
+	 */
 	getNodeType( builder, output ) {
 
 		const op = this.op;

+ 20 - 7
src/nodes/math/TriNoise3D.js

@@ -3,7 +3,9 @@
 import { Loop } from '../utils/LoopNode.js';
 import { float, vec3, Fn } from '../tsl/TSLBase.js';
 
-export const tri = /*@__PURE__*/ Fn( ( [ x ] ) => {
+/** @module TriNoise3D **/
+
+const tri = /*@__PURE__*/ Fn( ( [ x ] ) => {
 
 	return x.fract().sub( .5 ).abs();
 
@@ -15,7 +17,7 @@ export const tri = /*@__PURE__*/ Fn( ( [ x ] ) => {
 	]
 } );
 
-export const tri3 = /*@__PURE__*/ Fn( ( [ p ] ) => {
+const tri3 = /*@__PURE__*/ Fn( ( [ p ] ) => {
 
 	return vec3( tri( p.z.add( tri( p.y.mul( 1. ) ) ) ), tri( p.z.add( tri( p.x.mul( 1. ) ) ) ), tri( p.y.add( tri( p.x.mul( 1. ) ) ) ) );
 
@@ -27,9 +29,20 @@ export const tri3 = /*@__PURE__*/ Fn( ( [ p ] ) => {
 	]
 } );
 
-export const triNoise3D = /*@__PURE__*/ Fn( ( [ p_immutable, spd, time ] ) => {
+/** @module Hash **/
+
+/**
+ * Generates a noise value from the given position, speed and time parameters.
+ *
+ * @method
+ * @param {Node<vec3>} position - The position.
+ * @param {Node<float>} speed - The speed.
+ * @param {Node<float>} time - The time.
+ * @return {Node<float>} The generated noise.
+ */
+export const triNoise3D = /*@__PURE__*/ Fn( ( [ position, speed, time ] ) => {
 
-	const p = vec3( p_immutable ).toVar();
+	const p = vec3( position ).toVar();
 	const z = float( 1.4 ).toVar();
 	const rz = float( 0.0 ).toVar();
 	const bp = vec3( p ).toVar();
@@ -37,7 +50,7 @@ export const triNoise3D = /*@__PURE__*/ Fn( ( [ p_immutable, spd, time ] ) => {
 	Loop( { start: float( 0.0 ), end: float( 3.0 ), type: 'float', condition: '<=' }, () => {
 
 		const dg = vec3( tri3( bp.mul( 2.0 ) ) ).toVar();
-		p.addAssign( dg.add( time.mul( float( 0.1 ).mul( spd ) ) ) );
+		p.addAssign( dg.add( time.mul( float( 0.1 ).mul( speed ) ) ) );
 		bp.mulAssign( 1.8 );
 		z.mulAssign( 1.5 );
 		p.mulAssign( 1.2 );
@@ -54,8 +67,8 @@ export const triNoise3D = /*@__PURE__*/ Fn( ( [ p_immutable, spd, time ] ) => {
 	name: 'triNoise3D',
 	type: 'float',
 	inputs: [
-		{ name: 'p', type: 'vec3' },
-		{ name: 'spd', type: 'float' },
+		{ name: 'position', type: 'vec3' },
+		{ name: 'speed', type: 'float' },
 		{ name: 'time', type: 'float' }
 	]
 } );

+ 120 - 0
src/nodes/pmrem/PMREMNode.js

@@ -12,6 +12,13 @@ let _generator = null;
 
 const _cache = new WeakMap();
 
+/**
+ * Generates the cubeUV size based on the given image height.
+ *
+ * @private
+ * @param {Number} imageHeight - The image height.
+ * @return {{texelWidth: Number,texelHeight: Number, maxMip: Number}} The result object.
+ */
 function _generateCubeUVSize( imageHeight ) {
 
 	const maxMip = Math.log2( imageHeight ) - 2;
@@ -24,6 +31,13 @@ function _generateCubeUVSize( imageHeight ) {
 
 }
 
+/**
+ * Generates a PMREM from the given texture .
+ *
+ * @private
+ * @param {Texture} texture - The texture to create the PMREM for.
+ * @return {Texture} The PMREM.
+ */
 function _getPMREMFromTexture( texture ) {
 
 	let cacheTexture = _cache.get( texture );
@@ -71,6 +85,17 @@ function _getPMREMFromTexture( texture ) {
 
 }
 
+/**
+ * This node represents a PMREM which is a special type of preprocessed
+ * environment map intended for PBR materials.
+ *
+ * ```js
+ * const material = new MeshStandardNodeMaterial();
+ * material.envNode = pmremTexture( envMap );
+ * ```
+ *
+ * @augments TempNode
+ */
 class PMREMNode extends TempNode {
 
 	static get type() {
@@ -79,31 +104,107 @@ class PMREMNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new function overloading node.
+	 *
+	 * @param {Texture} texture - The input texture.
+	 * @param {Node<vec2>} [uvNode=null] - The uv node.
+	 * @param {Node<float>} [levelNode=null] - The level node.
+	 */
 	constructor( value, uvNode = null, levelNode = null ) {
 
 		super( 'vec3' );
 
+		/**
+		 * Reference to the input texture.
+		 *
+		 * @private
+		 * @type {Texture}
+		 */
 		this._value = value;
+
+		/**
+		 * Reference to the generated PMREM.
+		 *
+		 * @private
+		 * @type {Texture}
+		 * @default null
+		 */
 		this._pmrem = null;
 
+		/**
+		 *  The uv node.
+		 *
+		 * @type {Node<vec2>}
+		 */
 		this.uvNode = uvNode;
+
+		/**
+		 *  The level node.
+		 *
+		 * @type {Node<float>}
+		 */
 		this.levelNode = levelNode;
 
+		/**
+		 * Reference to a PMREM generator.
+		 *
+		 * @private
+		 * @type {PMREMGenerator}
+		 * @default null
+		 */
 		this._generator = null;
 
 		const defaultTexture = new Texture();
 		defaultTexture.isRenderTargetTexture = true;
 
+		/**
+		 * The texture node holding the generated PMREM.
+		 *
+		 * @private
+		 * @type {TextureNode}
+		 */
 		this._texture = texture( defaultTexture );
 
+		/**
+		 * A uniform representing the PMREM's width.
+		 *
+		 * @private
+		 * @type {UniformNode<float>}
+		 */
 		this._width = uniform( 0 );
+
+		/**
+		 * A uniform representing the PMREM's height.
+		 *
+		 * @private
+		 * @type {UniformNode<float>}
+		 */
 		this._height = uniform( 0 );
+
+		/**
+		 * A uniform representing the PMREM's max Mip.
+		 *
+		 * @private
+		 * @type {UniformNode<float>}
+		 */
 		this._maxMip = uniform( 0 );
 
+		/**
+		 * The `updateBeforeType` is set to `NodeUpdateType.RENDER`.
+		 *
+		 * @type {String}
+		 * @default 'render'
+		 */
 		this.updateBeforeType = NodeUpdateType.RENDER;
 
 	}
 
+	/**
+	 * The node's texture value.
+	 *
+	 * @type {Texture}
+	 */
 	set value( value ) {
 
 		this._value = value;
@@ -117,6 +218,11 @@ class PMREMNode extends TempNode {
 
 	}
 
+	/**
+	 * Uses the given PMREM texture to update internal values.
+	 *
+	 * @param {Texture} texture - The PMREM texture.
+	 */
 	updateFromTexture( texture ) {
 
 		const cubeUVSize = _generateCubeUVSize( texture.image.height );
@@ -211,6 +317,13 @@ class PMREMNode extends TempNode {
 
 export default PMREMNode;
 
+/**
+ * Returns `true` if the given cube map image has been fully loaded.
+ *
+ * @private
+ * @param {Array<(Image|Object)>} image - The cube map image.
+ * @return {Boolean} Whether the given cube map is ready or not.
+ */
 function isCubeMapReady( image ) {
 
 	if ( image === null || image === undefined ) return false;
@@ -229,6 +342,13 @@ function isCubeMapReady( image ) {
 
 }
 
+/**
+ * Returns `true` if the given equirectangular image has been fully loaded.
+ *
+ * @private
+ * @param {(Image|Object)} image - The equirectangular image.
+ * @return {Boolean} Whether the given cube map is ready or not.
+ */
 function isEquirectangularMapReady( image ) {
 
 	if ( image === null || image === undefined ) return false;

粤ICP备19079148号