Explorar o código

Node: Document more modules. (#30000)

* Node: Document more modules.

* Node: More docs.

* Node: More docs.

* Docs: Minor fix.

* Docs: More fixes.

* Docs: Fix TODOs.

* Update AssignNode.js
Michael Herzog hai 1 ano
pai
achega
f81793c461

+ 38 - 2
src/nodes/core/AssignNode.js

@@ -2,6 +2,12 @@ import TempNode from '../core/TempNode.js';
 import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js';
 import { vectorComponents } from '../core/constants.js';
 
+/**
+ * These node represents an assing operation. Meaning a node is assigned
+ * to another node.
+ *
+ * @augments TempNode
+ */
 class AssignNode extends TempNode {
 
 	static get type() {
@@ -10,15 +16,38 @@ class AssignNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new assign node.
+	 *
+	 * @param {Node} targetNode - The target node.
+	 * @param {Node} sourceNode - The source type.
+	 */
 	constructor( targetNode, sourceNode ) {
 
 		super();
 
+		/**
+		 * The target node.
+		 *
+		 * @type {Node}
+		 */
 		this.targetNode = targetNode;
+
+		/**
+		 * The source node.
+		 *
+		 * @type {Node}
+		 */
 		this.sourceNode = sourceNode;
 
 	}
 
+	/**
+	 * Whether this node is used more than once in contextx of other nodes. This method
+	 * is overwritten since it always returns `false` (assigns are unique).
+	 *
+	 * @return {Boolean} A flag that inidiactes if there is more than one dependency to other nodes. Always `false`.
+	 */
 	hasDependencies() {
 
 		return false;
@@ -31,6 +60,13 @@ class AssignNode extends TempNode {
 
 	}
 
+	/**
+	 * Whehter a split is required when assigning source to target. This can happen when the component length of
+	 * target and source data type does not match.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {Boolean} Whehter a split is required when assigning source to target.
+	 */
 	needsSplitAssign( builder ) {
 
 		const { targetNode } = this;
@@ -38,9 +74,9 @@ class AssignNode extends TempNode {
 		if ( builder.isAvailable( 'swizzleAssign' ) === false && targetNode.isSplitNode && targetNode.components.length > 1 ) {
 
 			const targetLength = builder.getTypeLength( targetNode.node.getNodeType( builder ) );
-			const assignDiferentVector = vectorComponents.join( '' ).slice( 0, targetLength ) !== targetNode.components;
+			const assignDifferentVector = vectorComponents.join( '' ).slice( 0, targetLength ) !== targetNode.components;
 
-			return assignDiferentVector;
+			return assignDifferentVector;
 
 		}
 

+ 33 - 0
src/nodes/core/AttributeNode.js

@@ -1,6 +1,11 @@
 import Node from './Node.js';
 import { nodeObject, varying } from '../tsl/TSLBase.js';
 
+/**
+ * Base class for representing shader attributes as nodes.
+ *
+ * @augments Node
+ */
 class AttributeNode extends Node {
 
 	static get type() {
@@ -9,10 +14,22 @@ class AttributeNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a new attribute node.
+	 *
+	 * @param {String} attributeName - The name of the attribute.
+	 * @param {String?} nodeType - The node type.
+	 */
 	constructor( attributeName, nodeType = null ) {
 
 		super( nodeType );
 
+		/**
+		 * `AttributeNode` sets this property to `true` by default.
+		 *
+		 * @type {Boolean}
+		 * @default true
+		 */
 		this.global = true;
 
 		this._attributeName = attributeName;
@@ -51,6 +68,14 @@ class AttributeNode extends Node {
 
 	}
 
+	/**
+	 * Sets the attribute name to the given value. The method can be
+	 * overwritten in derived classes if the final name must be computed
+	 * analytically.
+	 *
+	 * @param {String} attributeName - The name of the attribute.
+	 * @return {AttributeNode} A reference to this node.
+	 */
 	setAttributeName( attributeName ) {
 
 		this._attributeName = attributeName;
@@ -59,6 +84,14 @@ class AttributeNode extends Node {
 
 	}
 
+	/**
+	 * Returns the attribute name of this node. The method can be
+	 * overwritten in derived classes if the final name must be computed
+	 * analytically.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The attribute name.
+	 */
 	getAttributeName( /*builder*/ ) {
 
 		return this._attributeName;

+ 37 - 2
src/nodes/core/BypassNode.js

@@ -1,6 +1,17 @@
 import Node from './Node.js';
 import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js';
 
+/**
+ * The class generates the code of a given node but returns another node in the output.
+ * This can be used to call a method or node that does not return a value, i.e.
+ * type `void` on an input where returning a value is required. Example:
+ *
+ * ```js
+ * material.colorNode = myColor.bypass( runVoidFn() )
+ *```
+ *
+ * @augments Node
+ */
 class BypassNode extends Node {
 
 	static get type() {
@@ -9,13 +20,37 @@ class BypassNode extends Node {
 
 	}
 
-	constructor( returnNode, callNode ) {
+	/**
+	 * Constructs a new bypass node.
+	 *
+	 * @param {Node} outputNode - The output node.
+	 * @param {Node} callNode - The call node.
+	 */
+	constructor( outputNode, callNode ) {
 
 		super();
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isBypassNode = true;
 
-		this.outputNode = returnNode;
+		/**
+		 * The output node.
+		 *
+		 * @type {Node}
+		 */
+		this.outputNode = outputNode;
+
+		/**
+		 * The call node.
+		 *
+		 * @type {Node}
+		 */
 		this.callNode = callNode;
 
 	}

+ 32 - 0
src/nodes/core/CacheNode.js

@@ -1,6 +1,13 @@
 import Node from './Node.js';
 import { addMethodChaining, nodeObject } from '../tsl/TSLCore.js';
 
+/**
+ * This node can be used as a cache management component for another node.
+ * Caching is in general used by default in {@link NodeBuilder} but this node
+ * allows the usage of a shared parent cache during the build process.
+ *
+ * @augments Node
+ */
 class CacheNode extends Node {
 
 	static get type() {
@@ -9,13 +16,38 @@ class CacheNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a new cache node.
+	 *
+	 * @param {Node} node - The node that should be cached.
+	 * @param {Boolean} [parent=true] - Whether this node refers to a shared parent cache or not.
+	 */
 	constructor( node, parent = true ) {
 
 		super();
 
+		/**
+		 * The node that should be cached.
+		 *
+		 * @type {Node}
+		 */
 		this.node = node;
+
+		/**
+		 * Whether this node refers to a shared parent cache or not.
+		 *
+		 * @type {Boolean}
+		 * @default true
+		 */
 		this.parent = parent;
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isCacheNode = true;
 
 	}

+ 24 - 0
src/nodes/core/ConstNode.js

@@ -1,5 +1,10 @@
 import InputNode from './InputNode.js';
 
+/**
+ * Class for representing a constant value in the shader.
+ *
+ * @augments InputNode
+ */
 class ConstNode extends InputNode {
 
 	static get type() {
@@ -8,14 +13,33 @@ class ConstNode extends InputNode {
 
 	}
 
+	/**
+	 * Constructs a new input node.
+	 *
+	 * @param {Any} value - The value of this node. Usually a JS primitive or three.js object (vector, matrix, color).
+	 * @param {String?} nodeType - The node type. If no explicit type is defined, the node tries to derive the type from its value.
+	 */
 	constructor( value, nodeType = null ) {
 
 		super( value, nodeType );
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isConstNode = true;
 
 	}
 
+	/**
+	 * Generates the shader string of the value with the current node builder.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The generated value as a shader string.
+	 */
 	generateConst( builder ) {
 
 		return builder.generateConst( this.getNodeType( builder ), this.value );

+ 48 - 0
src/nodes/core/InputNode.js

@@ -1,6 +1,11 @@
 import Node from './Node.js';
 import { getValueType, getValueFromType, arrayBufferToBase64 } from './NodeUtils.js';
 
+/**
+ * Base class for representing data input nodes.
+ *
+ * @augments Node
+ */
 class InputNode extends Node {
 
 	static get type() {
@@ -9,13 +14,38 @@ class InputNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a new input node.
+	 *
+	 * @param {Any} value - The value of this node. This can be a any JS primitive, functions, array buffers or even three.js objects (vector, matrices, colors).
+	 * @param {String?} nodeType - The node type. If no explicit type is defined, the node tries to derive the type from its value.
+	 */
 	constructor( value, nodeType = null ) {
 
 		super( nodeType );
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isInputNode = true;
 
+		/**
+		 * The value of this node. This can be a any JS primitive, functions, array buffers or even three.js objects (vector, matrices, colors).
+		 *
+		 * @type {Any}
+		 */
 		this.value = value;
+
+		/**
+		 * The precision of the value in the shader.
+		 *
+		 * @type {('low'|'medium'|'high')?}
+		 * @default null
+		 */
 		this.precision = null;
 
 	}
@@ -32,12 +62,30 @@ class InputNode extends Node {
 
 	}
 
+	/**
+	 * Returns the input type of the node which is by default the node type. Derived modules
+	 * might overwrite this method and use a fixed type or compute one analytically.
+	 *
+	 * A typical example for differnt input and node types are textures. The input type of a
+	 * normal RGBA texture is `texture` whereas its node type is `vec4`.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The input type.
+	 */
 	getInputType( builder ) {
 
 		return this.getNodeType( builder );
 
 	}
 
+	/**
+	 * Sets the precision to the given value. The method can be
+	 * overwritten in derived classes if the final precision must be computed
+	 * analytically.
+	 *
+	 * @param {('low'|'medium'|'high')} precision - The precision of the input value in the shader.
+	 * @return {InputNode} A reference to this node.
+	 */
 	setPrecision( precision ) {
 
 		this.precision = precision;

+ 2 - 2
src/nodes/core/Node.js

@@ -80,7 +80,7 @@ class Node extends EventDispatcher {
 		/**
 		 * Whether this node is global or not. This property is relevant for the internal
 		 * node caching system. All nodes which should be declared just once should
-		 * set this flag to `true` (a typical example is `AttributeNode`).
+		 * set this flag to `true` (a typical example is {@link AttributeNode}).
 		 *
 		 * @type {Boolean}
 		 * @default false
@@ -88,7 +88,7 @@ class Node extends EventDispatcher {
 		this.global = false;
 
 		/**
-		 * This flag can be used for type testing (whether a given object is of type `Node` or not).
+		 * This flag can be used for type testing.
 		 *
 		 * @type {Boolean}
 		 * @readonly

+ 38 - 0
src/nodes/core/NodeAttribute.js

@@ -1,11 +1,49 @@
+/**
+ * {@link NodeBuilder} is going to create instances of this class during the build process
+ * of nodes. They represent the final shader attributes that are going to be generated
+ * by the builder. Arrays of node attributes is maintained in {@link NodeBuilder#attributes}
+ * and {@link NodeBuilder#bufferAttributes} for this purpose.
+ */
 class NodeAttribute {
 
+	/**
+	 * Constructs a new node attribute.
+	 *
+	 * @param {String} name - The name of the attribute.
+	 * @param {String} type - The type of the attribute.
+	 * @param {Node?} node - An optinal reference to the node.
+	 */
 	constructor( name, type, node = null ) {
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isNodeAttribute = true;
 
+		/**
+		 * The name of the attribute.
+		 *
+		 * @type {String}
+		 */
 		this.name = name;
+
+		/**
+		 * The type of the attribute.
+		 *
+		 * @type {String}
+		 */
 		this.type = type;
+
+		/**
+		 * An optinal reference to the node.
+		 *
+		 * @type {Node?}
+		 * @default null
+		 */
 		this.node = node;
 
 	}

+ 38 - 0
src/nodes/core/NodeBuilder.js

@@ -61,8 +61,19 @@ const toFloat = ( value ) => {
 
 };
 
+/**
+ * Base class for builders which generate a shader program based
+ * on a 3D object and its node material definition.
+ */
 class NodeBuilder {
 
+	/**
+	 * Constructs a new node builder.
+	 *
+	 * @param {Object3D} object - The 3D object.
+	 * @param {Renderer} renderer - The current renderer.
+	 * @param {NodeParser} parser - A reference to a node parser.
+	 */
 	constructor( object, renderer, parser ) {
 
 		this.object = object;
@@ -99,10 +110,37 @@ class NodeBuilder {
 		this.bindings = { vertex: {}, fragment: {}, compute: {} };
 		this.bindingsIndexes = {};
 		this.bindGroups = null;
+
+		/**
+		 * This array holds the node attributes of this builder
+		 * created via {@link AttributeNode}.
+		 *
+		 * @type {Array<NodeAttribute>}
+		 */
 		this.attributes = [];
+
+		/**
+		 * This array holds the node attributes of this builder
+		 * created via {@link BufferAttributeNode}.
+		 *
+		 * @type {Array<NodeAttribute>}
+		 */
 		this.bufferAttributes = [];
+
+		/**
+		 * This array holds the node varyings of this builder.
+		 *
+		 * @type {Array<NodeVarying>}
+		 */
 		this.varyings = [];
 		this.codes = {};
+
+		/**
+		 * This dictionary holds the node variables of this builder.
+		 * The variables are maintained in an array for each shader stage.
+		 *
+		 * @type {Object}
+		 */
 		this.vars = {};
 		this.flow = { code: '' };
 		this.chaining = [];

+ 30 - 0
src/nodes/core/NodeVar.js

@@ -1,10 +1,40 @@
+/**
+ * {@link NodeBuilder} is going to create instances of this class during the build process
+ * of nodes. They represent the final shader variables that are going to be generated
+ * by the builder. A dictionary of node variables is maintained in {@link NodeBuilder#vars} for
+ * this purpose.
+ */
 class NodeVar {
 
+	/**
+	 * Constructs a new node variable.
+	 *
+	 * @param {String} name - The name of the variable.
+	 * @param {String} type - The type of the variable.
+	 */
 	constructor( name, type ) {
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isNodeVar = true;
 
+		/**
+		 * The name of the variable.
+		 *
+		 * @type {String}
+		 */
 		this.name = name;
+
+		/**
+		 * The type of the variable.
+		 *
+		 * @type {String}
+		 */
 		this.type = type;
 
 	}

+ 28 - 0
src/nodes/core/NodeVarying.js

@@ -1,13 +1,41 @@
 import NodeVar from './NodeVar.js';
 
+/**
+ * {@link NodeBuilder} is going to create instances of this class during the build process
+ * of nodes. They represent the final shader varyings that are going to be generated
+ * by the builder. An array of node varyings is maintained in {@link NodeBuilder#varyings} for
+ * this purpose.
+ *
+ * @augments NodeVar
+ */
 class NodeVarying extends NodeVar {
 
+	/**
+	 * Constructs a new node varying.
+	 *
+	 * @param {String} name - The name of the varying.
+	 * @param {String} type - The type of the varying.
+	 */
 	constructor( name, type ) {
 
 		super( name, type );
 
+		/**
+		 * Whether this varying requires interpolation or not. This property can be used
+		 * to check if the varying can be optimized for a variable.
+		 *
+		 * @type {Boolean}
+		 * @default false
+		 */
 		this.needsInterpolation = false;
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isNodeVarying = true;
 
 	}

+ 25 - 0
src/nodes/core/TempNode.js

@@ -1,5 +1,13 @@
 import Node from './Node.js';
 
+/**
+ * This module uses cache management to create temporary variables
+ * if the node is used more than once to prevent duplicate calculations.
+ *
+ * The class acts as a base class for many other nodes types.
+ *
+ * @augments Node
+ */
 class TempNode extends Node {
 
 	static get type() {
@@ -8,14 +16,31 @@ class TempNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a temp node.
+	 *
+	 * @param {String} nodeType - The node type.
+	 */
 	constructor( type ) {
 
 		super( type );
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isTempNode = true;
 
 	}
 
+	/**
+	 * Whether this node is used more than once in context of other nodes.
+	 *
+	 * @return {Boolean} A flag that inidiactes if there is more than one dependency to other nodes.
+	 */
 	hasDependencies( builder ) {
 
 		return builder.getDataFromNode( this ).usageCount > 1;

+ 47 - 7
src/nodes/core/UniformGroupNode.js

@@ -1,5 +1,18 @@
 import Node from './Node.js';
 
+/**
+ * This node can be used to group single instances of {@link UniformNode}
+ * and manage them as a uniform buffer.
+ *
+ * In most cases, the predefined nodes `objectGroup`, `renderGroup` and `frameGroup`
+ * will be used when defining the {@link UniformNode#groupNode} property.
+ *
+ * - `objectGroup`: Uniform buffer per object.
+ * - `renderGroup`: Shared uniform buffer, updated once per render call.
+ * - `frameGroup`: Shared uniform buffer, updated once per frame.
+ *
+ * @augments Node
+ */
 class UniformGroupNode extends Node {
 
 	static get type() {
@@ -8,22 +21,49 @@ class UniformGroupNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a new uniform group node.
+	 *
+	 * @param {String} name - The name of the uniform group node.
+	 * @param {Boolean} [shared=false] - Whether this uniform group node is shared or not.
+	 * @param {Number} [order=1] - Influences the internal sorting.
+	 */
 	constructor( name, shared = false, order = 1 ) {
 
 		super( 'string' );
 
+		/**
+		 * The name of the uniform group node.
+		 *
+		 * @type {String}
+		 */
 		this.name = name;
-		this.version = 0;
 
+		/**
+		 * Whether this uniform group node is shared or not.
+		 *
+		 * @type {Boolean}
+		 * @default false
+		 */
 		this.shared = shared;
-		this.order = order;
-		this.isUniformGroup = true;
-
-	}
 
-	set needsUpdate( value ) {
+		/**
+		 * Influences the internal sorting.
+		 * TODO: Add details when this property should be changed.
+		 *
+		 * @type {Number}
+		 * @default 1
+		 */
+		this.order = order;
 
-		if ( value === true ) this.version ++;
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
+		this.isUniformGroup = true;
 
 	}
 

+ 56 - 0
src/nodes/core/UniformNode.js

@@ -2,6 +2,11 @@ import InputNode from './InputNode.js';
 import { objectGroup } from './UniformGroupNode.js';
 import { nodeObject, getConstNodeType } from '../tsl/TSLCore.js';
 
+/**
+ * Class for representing a uniform.
+ *
+ * @augments InputNode
+ */
 class UniformNode extends InputNode {
 
 	static get type() {
@@ -10,17 +15,50 @@ class UniformNode extends InputNode {
 
 	}
 
+	/**
+	 * Constructs a new uniform node.
+	 *
+	 * @param {Any} value - The value of this node. Usually a JS primitive or three.js object (vector, matrix, color, texture).
+	 * @param {String?} nodeType - The node type. If no explicit type is defined, the node tries to derive the type from its value.
+	 */
 	constructor( value, nodeType = null ) {
 
 		super( value, nodeType );
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isUniformNode = true;
 
+		/**
+		 * The name or label of the uniform.
+		 *
+		 * @type {String}
+		 * @default ''
+		 */
 		this.name = '';
+
+		/**
+		 * The uniform group of this uniform. By default, uniforms are
+		 * managed per object but they might belong to a shared group
+		 * which is updated per frame or render call.
+		 *
+		 * @type {UniformGroupNode}
+		 */
 		this.groupNode = objectGroup;
 
 	}
 
+	/**
+	 * Sets the {@link UniformNode#name} property.
+	 *
+	 * @param {String} name - The name of the uniform.
+	 * @return {UniformNode} A reference to this node.
+	 */
 	label( name ) {
 
 		this.name = name;
@@ -29,6 +67,12 @@ class UniformNode extends InputNode {
 
 	}
 
+	/**
+	 * Sets the {@link UniformNode#groupNode} property.
+	 *
+	 * @param {UniformGroupNode} group - The uniform group.
+	 * @return {UniformNode} A reference to this node.
+	 */
 	setGroup( group ) {
 
 		this.groupNode = group;
@@ -37,12 +81,24 @@ class UniformNode extends InputNode {
 
 	}
 
+	/**
+	 * Returns the {@link UniformNode#groupNode}.
+	 *
+	 * @return {UniformGroupNode} The uniform group.
+	 */
 	getGroup() {
 
 		return this.groupNode;
 
 	}
 
+	/**
+	 * By default, this method returns the result of {@link Node#getHash} but derived
+	 * classes might overwrite this method with a different implementation.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The uniform hash.
+	 */
 	getUniformHash( builder ) {
 
 		return this.getHash( builder );

+ 26 - 1
src/nodes/core/constants.js

@@ -1,4 +1,9 @@
-
+/**
+ * Possible shader stages.
+ *
+ * @property {string} VERTEX The vertex shader stage.
+ * @property {string} FRAGMENT The fragment shader stage.
+ */
 export const NodeShaderStage = {
 	VERTEX: 'vertex',
 	FRAGMENT: 'fragment'
@@ -19,6 +24,19 @@ export const NodeUpdateType = {
 	OBJECT: 'object'
 };
 
+/**
+ * Data types of a node.
+ *
+ * @property {string} BOOLEAN Boolean type.
+ * @property {string} INTEGER Integer type.
+ * @property {string} FLOAT Float type.
+ * @property {string} VECTOR2 Two-dimensional vector type.
+ * @property {string} VECTOR3 Three-dimensional vector type.
+ * @property {string} VECTOR4 Four-dimensional vector type.
+ * @property {string} MATRIX2 2x2 matrix type.
+ * @property {string} MATRIX3 3x3 matrix type.
+ * @property {string} MATRIX4 4x4 matrix type.
+ */
 export const NodeType = {
 	BOOLEAN: 'bool',
 	INTEGER: 'int',
@@ -31,6 +49,13 @@ export const NodeType = {
 	MATRIX4: 'mat4'
 };
 
+/**
+ * Access types of a node. These are relevant for compute and storage usage.
+ *
+ * @property {string} READ_ONLY Read-only access
+ * @property {string} WRITE_ONLY Write-only access.
+ * @property {string} READ_WRITE Read and write access.
+ */
 export const NodeAccess = {
 	READ_ONLY: 'readOnly',
 	WRITE_ONLY: 'writeOnly',

粤ICP备19079148号