Parcourir la source

Node: Document more modules. (#30123)

* Node: Document more modules.

* Node: Document more modules.

* Exampels: Clean up.
Michael Herzog il y a 1 an
Parent
commit
0f523acc5a

+ 9 - 9
examples/webgpu_compute_sort_bitonic.html

@@ -55,7 +55,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import { storageObject, If, vec3, not, uniform, uv, uint, float, Fn, vec2, abs, int, invocationLocalIndex, workgroupArray, uvec2, floor, instanceIndex, workgroupBarrier, atomicAdd, atomicStore, workgroupId } from 'three/tsl';
+			import { storage, If, vec3, not, uniform, uv, uint, float, Fn, vec2, abs, int, invocationLocalIndex, workgroupArray, uvec2, floor, instanceIndex, workgroupBarrier, atomicAdd, atomicStore, workgroupId } from 'three/tsl';
 
 			import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 
@@ -141,17 +141,17 @@
 
 				const nextAlgoBuffer = new THREE.StorageInstancedBufferAttribute( new Uint32Array( 1 ).fill( forceGlobalSwap ? StepType.FLIP_GLOBAL : StepType.FLIP_LOCAL ), 1 );
 
-				const nextAlgoStorage = storageObject( nextAlgoBuffer, 'uint', nextAlgoBuffer.count ).label( 'NextAlgo' );
+				const nextAlgoStorage = storage( nextAlgoBuffer, 'uint', nextAlgoBuffer.count ).setPBO( true ).label( 'NextAlgo' );
 
 				const nextBlockHeightBuffer = new THREE.StorageInstancedBufferAttribute( new Uint32Array( 1 ).fill( 2 ), 1 );
-				const nextBlockHeightStorage = storageObject( nextBlockHeightBuffer, 'uint', nextBlockHeightBuffer.count ).label( 'NextBlockHeight' );
-				const nextBlockHeightRead = storageObject( nextBlockHeightBuffer, 'uint', nextBlockHeightBuffer.count ).label( 'NextBlockHeight' ).toReadOnly();
+				const nextBlockHeightStorage = storage( nextBlockHeightBuffer, 'uint', nextBlockHeightBuffer.count ).setPBO( true ).label( 'NextBlockHeight' );
+				const nextBlockHeightRead = storage( nextBlockHeightBuffer, 'uint', nextBlockHeightBuffer.count ).setPBO( true ).label( 'NextBlockHeight' ).toReadOnly();
 
 				const highestBlockHeightBuffer = new THREE.StorageInstancedBufferAttribute( new Uint32Array( 1 ).fill( 2 ), 1 );
-				const highestBlockHeightStorage = storageObject( highestBlockHeightBuffer, 'uint', highestBlockHeightBuffer.count ).label( 'HighestBlockHeight' );
+				const highestBlockHeightStorage = storage( highestBlockHeightBuffer, 'uint', highestBlockHeightBuffer.count ).setPBO( true ).label( 'HighestBlockHeight' );
 
 				const counterBuffer = new THREE.StorageBufferAttribute( 1, 1 );
-				const counterStorage = storageObject( counterBuffer, 'uint', counterBuffer.count ).toAtomic().label( 'Counter' );
+				const counterStorage = storage( counterBuffer, 'uint', counterBuffer.count ).setPBO( true ).toAtomic().label( 'Counter' );
 
 				const array = new Uint32Array( Array.from( { length: size }, ( _, i ) => {
 
@@ -179,11 +179,11 @@
 				randomizeDataArray();
 
 				const currentElementsBuffer = new THREE.StorageInstancedBufferAttribute( array, 1 );
-				const currentElementsStorage = storageObject( currentElementsBuffer, 'uint', size ).label( 'Elements' );
+				const currentElementsStorage = storage( currentElementsBuffer, 'uint', size ).setPBO( true ).label( 'Elements' );
 				const tempBuffer = new THREE.StorageInstancedBufferAttribute( array, 1 );
-				const tempStorage = storageObject( tempBuffer, 'uint', size ).label( 'Temp' );
+				const tempStorage = storage( tempBuffer, 'uint', size ).setPBO( true ).label( 'Temp' );
 				const randomizedElementsBuffer = new THREE.StorageInstancedBufferAttribute( size, 1 );
-				const randomizedElementsStorage = storageObject( randomizedElementsBuffer, 'uint', size ).label( 'RandomizedElements' );
+				const randomizedElementsStorage = storage( randomizedElementsBuffer, 'uint', size ).setPBO( true ).label( 'RandomizedElements' );
 
 				const getFlipIndices = ( index, blockHeight ) => {
 

+ 18 - 1
src/nodes/accessors/Arrays.js

@@ -3,6 +3,16 @@ import StorageBufferAttribute from '../../renderers/common/StorageBufferAttribut
 import { storage } from './StorageBufferNode.js';
 import { getLengthFromType } from '../core/NodeUtils.js';
 
+/** @module Arrays **/
+
+/**
+ * TSL function for creating a storage buffer node with a configured `StorageBufferAttribute`.
+ *
+ * @function
+ * @param {Number} count - The data count.
+ * @param {String} [type='float'] - The data type.
+ * @returns {StorageBufferNode}
+ */
 export const attributeArray = ( count, type = 'float' ) => {
 
 	const itemSize = getLengthFromType( type );
@@ -14,7 +24,14 @@ export const attributeArray = ( count, type = 'float' ) => {
 
 };
 
-
+/**
+ * TSL function for creating a storage buffer node with a configured `StorageInstancedBufferAttribute`.
+ *
+ * @function
+ * @param {Number} count - The data count.
+ * @param {String} [type='float'] - The data type.
+ * @returns {StorageBufferNode}
+ */
 export const instancedArray = ( count, type = 'float' ) => {
 
 	const itemSize = getLengthFromType( type );

+ 178 - 5
src/nodes/accessors/BufferAttributeNode.js

@@ -6,6 +6,30 @@ import { InterleavedBufferAttribute } from '../../core/InterleavedBufferAttribut
 import { InterleavedBuffer } from '../../core/InterleavedBuffer.js';
 import { StaticDrawUsage, DynamicDrawUsage } from '../../constants.js';
 
+/** @module BufferAttributeNode **/
+
+/**
+ * In earlier `three.js` versions it was only possible to define attribute data
+ * on geometry level. With `BufferAttributeNode`, it is also possible to do this
+ * on the node level.
+ * ```js
+ * const geometry = new THREE.PlaneGeometry();
+ * const positionAttribute = geometry.getAttribute( 'position' );
+ *
+ * const colors = [];
+ * for ( let i = 0; i < position.count; i ++ ) {
+ * 	colors.push( 1, 0, 0 );
+ * }
+ *
+ * material.colorNode = bufferAttribute( new THREE.Float32BufferAttribute( colors, 3 ) );
+ * ```
+ * This new approach is especially interesting when geometry data are generated via
+ * compute shaders. The below line converts a storage buffer into an attribute.
+ * ```js
+ * material.positionNode = positionBuffer.toAttribute();
+ * ```
+ * @augments InputNode
+ */
 class BufferAttributeNode extends InputNode {
 
 	static get type() {
@@ -14,21 +38,82 @@ class BufferAttributeNode extends InputNode {
 
 	}
 
+	/**
+	 * Constructs a new buffer attribute node.
+	 *
+	 * @param {BufferAttribute|InterleavedBuffer|TypedArray} value - The attribute data.
+	 * @param {String?} [bufferType=null] - The buffer type (e.g. `'vec3'`).
+	 * @param {Number} [bufferStride=0] - The buffer stride.
+	 * @param {Number} [bufferOffset=0] - The buffer offset.
+	 */
 	constructor( value, bufferType = null, bufferStride = 0, bufferOffset = 0 ) {
 
 		super( value, bufferType );
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isBufferNode = true;
 
+		/**
+		 * The buffer type (e.g. `'vec3'`).
+		 *
+		 * @type {String}
+		 * @default null
+		 */
 		this.bufferType = bufferType;
+
+		/**
+		 * The buffer stride.
+		 *
+		 * @type {Number}
+		 * @default 0
+		 */
 		this.bufferStride = bufferStride;
+
+		/**
+		 * The buffer offset.
+		 *
+		 * @type {Number}
+		 * @default 0
+		 */
 		this.bufferOffset = bufferOffset;
 
+		/**
+		 * The usage property. Set this to `THREE.DynamicDrawUsage` via `.setUsage()`,
+		 * if you are planning to update the attribute data per frame.
+		 *
+		 * @type {Number}
+		 * @default StaticDrawUsage
+		 */
 		this.usage = StaticDrawUsage;
+
+		/**
+		 * Whether the attribute is instanced or not.
+		 *
+		 * @type {Boolean}
+		 * @default false
+		 */
 		this.instanced = false;
 
+		/**
+		 * A reference to the buffer attribute.
+		 *
+		 * @type {BufferAttribute?}
+		 * @default null
+		 */
 		this.attribute = null;
 
+		/**
+		 * `BufferAttributeNode` sets this property to `true` by default.
+		 *
+		 * @type {Boolean}
+		 * @default true
+		 */
 		this.global = true;
 
 		if ( value && value.isBufferAttribute === true ) {
@@ -41,6 +126,13 @@ class BufferAttributeNode extends InputNode {
 
 	}
 
+	/**
+	 * This method is overwritten since the attribute data might be shared
+	 * and thus the hash should be shared as well.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The hash.
+	 */
 	getHash( builder ) {
 
 		if ( this.bufferStride === 0 && this.bufferOffset === 0 ) {
@@ -65,6 +157,13 @@ class BufferAttributeNode extends InputNode {
 
 	}
 
+	/**
+	 * This method is overwritten since the node type is inferred from
+	 * the buffer attribute.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The node type.
+	 */
 	getNodeType( builder ) {
 
 		if ( this.bufferType === null ) {
@@ -77,6 +176,13 @@ class BufferAttributeNode extends InputNode {
 
 	}
 
+	/**
+	 * Depending on which value was passed to the node, `setup()` behaves
+	 * differently. If no instance of `BufferAttribute` was passed, the method
+	 * creates an internal attribute and configures it respectively.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 */
 	setup( builder ) {
 
 		if ( this.attribute !== null ) return;
@@ -97,6 +203,12 @@ class BufferAttributeNode extends InputNode {
 
 	}
 
+	/**
+	 * Generates the code snippet of the buffer attribute node.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The generated code snippet.
+	 */
 	generate( builder ) {
 
 		const nodeType = this.getNodeType( builder );
@@ -124,12 +236,24 @@ class BufferAttributeNode extends InputNode {
 
 	}
 
+	/**
+	 * Overwrites the default implementation to return a fixed value `'bufferAttribute'`.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The input type.
+	 */
 	getInputType( /*builder*/ ) {
 
 		return 'bufferAttribute';
 
 	}
 
+	/**
+	 * Sets the `usage` property to the given value.
+	 *
+	 * @param {Number} value - The usage to set.
+	 * @return {BufferAttributeNode} A reference to this node.
+	 */
 	setUsage( value ) {
 
 		this.usage = value;
@@ -144,6 +268,12 @@ class BufferAttributeNode extends InputNode {
 
 	}
 
+	/**
+	 * Sets the `instanced` property to the given value.
+	 *
+	 * @param {Number} value - The value to set.
+	 * @return {BufferAttributeNode} A reference to this node.
+	 */
 	setInstanced( value ) {
 
 		this.instanced = value;
@@ -156,10 +286,53 @@ class BufferAttributeNode extends InputNode {
 
 export default BufferAttributeNode;
 
-export const bufferAttribute = ( array, type, stride, offset ) => nodeObject( new BufferAttributeNode( array, type, stride, offset ) );
-export const dynamicBufferAttribute = ( array, type, stride, offset ) => bufferAttribute( array, type, stride, offset ).setUsage( DynamicDrawUsage );
-
-export const instancedBufferAttribute = ( array, type, stride, offset ) => bufferAttribute( array, type, stride, offset ).setInstanced( true );
-export const instancedDynamicBufferAttribute = ( array, type, stride, offset ) => dynamicBufferAttribute( array, type, stride, offset ).setInstanced( true );
+/**
+ * TSL function for creating a buffer attribute node.
+ *
+ * @function
+ * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data.
+ * @param {String?} [type=null] - The buffer type (e.g. `'vec3'`).
+ * @param {Number} [stride=0] - The buffer stride.
+ * @param {Number} [offset=0] - The buffer offset.
+ * @returns {BufferAttributeNode}
+ */
+export const bufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => nodeObject( new BufferAttributeNode( array, type, stride, offset ) );
+
+/**
+ * TSL function for creating a buffer attribute node but with dynamic draw usage.
+ * Use this function if attribute data are updated per frame.
+ *
+ * @function
+ * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data.
+ * @param {String?} [type=null] - The buffer type (e.g. `'vec3'`).
+ * @param {Number} [stride=0] - The buffer stride.
+ * @param {Number} [offset=0] - The buffer offset.
+ * @returns {BufferAttributeNode}
+ */
+export const dynamicBufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => bufferAttribute( array, type, stride, offset ).setUsage( DynamicDrawUsage );
+
+/**
+ * TSL function for creating a buffer attribute node but with enabled instancing
+ *
+ * @function
+ * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data.
+ * @param {String?} [type=null] - The buffer type (e.g. `'vec3'`).
+ * @param {Number} [stride=0] - The buffer stride.
+ * @param {Number} [offset=0] - The buffer offset.
+ * @returns {BufferAttributeNode}
+ */
+export const instancedBufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => bufferAttribute( array, type, stride, offset ).setInstanced( true );
+
+/**
+ * TSL function for creating a buffer attribute node but with dynamic draw usage and enabled instancing
+ *
+ * @function
+ * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data.
+ * @param {String?} [type=null] - The buffer type (e.g. `'vec3'`).
+ * @param {Number} [stride=0] - The buffer stride.
+ * @param {Number} [offset=0] - The buffer offset.
+ * @returns {BufferAttributeNode}
+ */
+export const instancedDynamicBufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => dynamicBufferAttribute( array, type, stride, offset ).setInstanced( true );
 
 addMethodChaining( 'toAttribute', ( bufferNode ) => bufferAttribute( bufferNode.value ) );

+ 71 - 2
src/nodes/accessors/ClippingNode.js

@@ -8,6 +8,16 @@ import { smoothstep } from '../math/MathNode.js';
 import { uniformArray } from './UniformArrayNode.js';
 import { builtin } from './BuiltinNode.js';
 
+/** @module ClippingNode **/
+
+/**
+ * ```
+ * This node is used in {@link NodeMaterial} to setup the clipping
+ * which can happen hardware-accelerated (if supported) and optionally
+ * use alpha-to-coverage for anti-aliasing clipped edges.
+ * ```
+ * @augments Node
+ */
 class ClippingNode extends Node {
 
 	static get type() {
@@ -16,14 +26,32 @@ class ClippingNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a new clipping node.
+	 *
+	 * @param {('default'|'hardware'|'alphaToCoverage')} [scope='default'] - The node's scope. Similar to other nodes,
+	 * the selected scope influences the behavior of the node and what type of code is generated.
+	 */
 	constructor( scope = ClippingNode.DEFAULT ) {
 
 		super();
 
+		/**
+		 * The node's scope. Similar to other nodes, the selected scope influences
+		 * the behavior of the node and what type of code is generated.
+		 *
+		 * @type {('default'|'hardware'|'alphaToCoverage')}
+		 */
 		this.scope = scope;
 
 	}
 
+	/**
+	 * Setups the node depending on the selected scope.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {Node} The result node.
+	 */
 	setup( builder ) {
 
 		super.setup( builder );
@@ -49,6 +77,13 @@ class ClippingNode extends Node {
 
 	}
 
+	/**
+	 * Setups alpha to coverage.
+	 *
+	 * @param {Array<Vector4>} intersectionPlanes - The intersection planes.
+	 * @param {Array<Vector4>} unionPlanes - The union planes.
+	 * @return {Node} The result node.
+	 */
 	setupAlphaToCoverage( intersectionPlanes, unionPlanes ) {
 
 		return Fn( () => {
@@ -60,7 +95,7 @@ class ClippingNode extends Node {
 
 			const numUnionPlanes = unionPlanes.length;
 
-			if ( ! this.hardwareClipping && numUnionPlanes > 0 ) {
+			if ( this.hardwareClipping === false && numUnionPlanes > 0 ) {
 
 				const clippingPlanes = uniformArray( unionPlanes );
 
@@ -107,13 +142,20 @@ class ClippingNode extends Node {
 
 	}
 
+	/**
+	 * Setups the default clipping.
+	 *
+	 * @param {Array<Vector4>} intersectionPlanes - The intersection planes.
+	 * @param {Array<Vector4>} unionPlanes - The union planes.
+	 * @return {Node} The result node.
+	 */
 	setupDefault( intersectionPlanes, unionPlanes ) {
 
 		return Fn( () => {
 
 			const numUnionPlanes = unionPlanes.length;
 
-			if ( ! this.hardwareClipping && numUnionPlanes > 0 ) {
+			if ( this.hardwareClipping === false && numUnionPlanes > 0 ) {
 
 				const clippingPlanes = uniformArray( unionPlanes );
 
@@ -148,6 +190,13 @@ class ClippingNode extends Node {
 
 	}
 
+	/**
+	 * Setups hardware clipping.
+	 *
+	 * @param {Array<Vector4>} unionPlanes - The union planes.
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {Node} The result node.
+	 */
 	setupHardwareClipping( unionPlanes, builder ) {
 
 		const numUnionPlanes = unionPlanes.length;
@@ -180,6 +229,26 @@ ClippingNode.HARDWARE = 'hardware';
 
 export default ClippingNode;
 
+/**
+ * TSL function for setting up the default clipping logic.
+ *
+ * @function
+ * @returns {ClippingNode}
+ */
 export const clipping = () => nodeObject( new ClippingNode() );
+
+/**
+ * TSL function for setting up alpha to coverage.
+ *
+ * @function
+ * @returns {ClippingNode}
+ */
 export const clippingAlpha = () => nodeObject( new ClippingNode( ClippingNode.ALPHA_TO_COVERAGE ) );
+
+/**
+ * TSL function for setting up hardware-based clipping.
+ *
+ * @function
+ * @returns {ClippingNode}
+ */
 export const hardwareClipping = () => nodeObject( new ClippingNode( ClippingNode.HARDWARE ) );

+ 188 - 0
src/nodes/accessors/ReferenceBaseNode.js

@@ -4,6 +4,17 @@ import { uniform } from '../core/UniformNode.js';
 import { nodeObject } from '../tsl/TSLCore.js';
 import ArrayElementNode from '../utils/ArrayElementNode.js';
 
+// TODO: Avoid duplicated code and ues only ReferenceBaseNode or ReferenceNode
+
+/** @module ReferenceBaseNode **/
+
+/**
+ * This class is only relevant if the referenced property is array-like.
+ * In this case, `ReferenceElementNode` allows to refer to a specific
+ * element inside the data structure via an index.
+ *
+ * @augments ArrayElementNode
+ */
 class ReferenceElementNode extends ArrayElementNode {
 
 	static get type() {
@@ -12,16 +23,43 @@ class ReferenceElementNode extends ArrayElementNode {
 
 	}
 
+	/**
+	 * Constructs a new reference element node.
+	 *
+	 * @param {Node?} referenceNode - The reference node.
+	 * @param {Node} indexNode - The index node that defines the element access.
+	 */
 	constructor( referenceNode, indexNode ) {
 
 		super( referenceNode, indexNode );
 
+		/**
+		 * Similar to {@link module:ReferenceBaseNode~ReferenceBaseNode#reference}, an additional
+		 * property references to the current node.
+		 *
+		 * @type {Node?}
+		 * @default null
+		 */
 		this.referenceNode = referenceNode;
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isReferenceElementNode = true;
 
 	}
 
+	/**
+	 * This method is overwritten since the node type is inferred from
+	 * the uniform type of the reference node.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The node type.
+	 */
 	getNodeType() {
 
 		return this.referenceNode.uniformType;
@@ -40,6 +78,14 @@ class ReferenceElementNode extends ArrayElementNode {
 
 }
 
+/**
+ * Base class for nodes which establishe a reference to a property of another object.
+ * In this way, the value of the node is automatically linked to the value of
+ * referenced object. Reference nodes internally represent the linked value
+ * as a uniform.
+ *
+ * @augments Node
+ */
 class ReferenceBaseNode extends Node {
 
 	static get type() {
@@ -48,24 +94,97 @@ class ReferenceBaseNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a new reference base node.
+	 *
+	 * @param {String} property - The name of the property the node refers to.
+	 * @param {String} uniformType - The uniform type that should be used to represent the property value.
+	 * @param {Object?} [object=null] - The object the property belongs to.
+	 * @param {Number?} [count=null] - When the linked property is an array-like, this parameter defines its length.
+	 */
 	constructor( property, uniformType, object = null, count = null ) {
 
 		super();
 
+		/**
+		 * The name of the property the node refers to.
+		 *
+		 * @type {String}
+		 */
 		this.property = property;
+
+		/**
+		 * The uniform type that should be used to represent the property value.
+		 *
+		 * @type {String}
+		 */
 		this.uniformType = uniformType;
+
+		/**
+		 * The object the property belongs to.
+		 *
+		 * @type {Object?}
+		 * @default null
+		 */
 		this.object = object;
+
+		/**
+		 * When the linked property is an array, this parameter defines its length.
+		 *
+		 * @type {Number?}
+		 * @default null
+		 */
 		this.count = count;
 
+		/**
+		 * The property name might have dots so nested properties can be referred.
+		 * The hierarchy of the names is stored inside this array.
+		 *
+		 * @type {Array<String>}
+		 */
 		this.properties = property.split( '.' );
+
+		/**
+		 * Points to the current referred object. This property exists next to {@link module:ReferenceNode~ReferenceNode#object}
+		 * since the final reference might be updated from calling code.
+		 *
+		 * @type {Object?}
+		 * @default null
+		 */
 		this.reference = object;
+
+		/**
+		 * The uniform node that holds the value of the reference node.
+		 *
+		 * @type {UniformNode}
+		 * @default null
+		 */
 		this.node = null;
+
+		/**
+		 * The uniform group of the internal uniform.
+		 *
+		 * @type {UniformGroupNode}
+		 * @default null
+		 */
 		this.group = null;
 
+		/**
+		 * Overwritten since reference nodes are updated per object.
+		 *
+		 * @type {String}
+		 * @default 'object'
+		 */
 		this.updateType = NodeUpdateType.OBJECT;
 
 	}
 
+	/**
+	 * Sets the uniform group for this reference node.
+	 *
+	 * @param {UniformGroupNode} group - The uniform group to set.
+	 * @return {ReferenceBaseNode} A reference to this node.
+	 */
 	setGroup( group ) {
 
 		this.group = group;
@@ -74,12 +193,25 @@ class ReferenceBaseNode extends Node {
 
 	}
 
+	/**
+	 * When the referred property is array-like, this method can be used
+	 * to access elements via an index node.
+	 *
+	 * @param {IndexNode} indexNode - indexNode.
+	 * @return {ReferenceElementNode} A reference to an element.
+	 */
 	element( indexNode ) {
 
 		return nodeObject( new ReferenceElementNode( this, nodeObject( indexNode ) ) );
 
 	}
 
+	/**
+	 * Sets the node type which automatically defines the internal
+	 * uniform type.
+	 *
+	 * @param {String} uniformType - The type to set.
+	 */
 	setNodeType( uniformType ) {
 
 		const node = uniform( null, uniformType ).getSelf();
@@ -94,6 +226,13 @@ class ReferenceBaseNode extends Node {
 
 	}
 
+	/**
+	 * This method is overwritten since the node type is inferred from
+	 * the type of the reference node.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The node type.
+	 */
 	getNodeType( builder ) {
 
 		if ( this.node === null ) {
@@ -107,6 +246,12 @@ class ReferenceBaseNode extends Node {
 
 	}
 
+	/**
+	 * Returns the property value from the given referred object.
+	 *
+	 * @param {Object} [object=this.reference] - The object to retrieve the property value from.
+	 * @return {Any} The value.
+	 */
 	getValueFromReference( object = this.reference ) {
 
 		const { properties } = this;
@@ -123,6 +268,13 @@ class ReferenceBaseNode extends Node {
 
 	}
 
+	/**
+	 * Allows to update the reference based on the given state. The state is only
+	 * evaluated {@link module:ReferenceBaseNode~ReferenceBaseNode#object} is not set.
+	 *
+	 * @param {(NodeFrame|NodeBuilder)} state - The current state.
+	 * @return {Object} The updated reference.
+	 */
 	updateReference( state ) {
 
 		this.reference = this.object !== null ? this.object : state.object;
@@ -131,6 +283,12 @@ class ReferenceBaseNode extends Node {
 
 	}
 
+	/**
+	 * The output of the reference node is the internal uniform node.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {UniformNode} The output node.
+	 */
 	setup() {
 
 		this.updateValue();
@@ -139,12 +297,21 @@ class ReferenceBaseNode extends Node {
 
 	}
 
+	/**
+	 * Overwritten to to update the internal uniform value.
+	 *
+	 * @param {NodeFrame} frame - A reference to the current node frame.
+	 */
 	update( /*frame*/ ) {
 
 		this.updateValue();
 
 	}
 
+	/**
+	 * Retrieves the value from the referred object property and uses it
+	 * to updated the internal uniform.
+	 */
 	updateValue() {
 
 		if ( this.node === null ) this.setNodeType( this.uniformType );
@@ -167,5 +334,26 @@ class ReferenceBaseNode extends Node {
 
 export default ReferenceBaseNode;
 
+/**
+ * TSL function for creating a reference base node.
+ *
+ * @function
+ * @param {String} name - The name of the property the node refers to.
+ * @param {String} type - The uniform type that should be used to represent the property value.
+ * @param {Object} object - The object the property belongs to.
+ * @returns {ReferenceBaseNode}
+ */
 export const reference = ( name, type, object ) => nodeObject( new ReferenceBaseNode( name, type, object ) );
+
+/**
+ * TSL function for creating a reference base node. Use this function if you want need a reference
+ * to an array-like property that should be represented as a uniform buffer.
+ *
+ * @function
+ * @param {String} name - The name of the property the node refers to.
+ * @param {String} type - The uniform type that should be used to represent the property value.
+ * @param {Number} count - The number of value inside the array-like object.
+ * @param {Object} object - An array-like object the property belongs to.
+ * @returns {ReferenceBaseNode}
+ */
 export const referenceBuffer = ( name, type, count, object ) => nodeObject( new ReferenceBaseNode( name, type, object, count ) );

+ 5 - 3
src/nodes/accessors/ReferenceNode.js

@@ -8,6 +8,8 @@ import { nodeObject } from '../tsl/TSLBase.js';
 import { uniformArray } from './UniformArrayNode.js';
 import ArrayElementNode from '../utils/ArrayElementNode.js';
 
+// TODO: Avoid duplicated code and ues only ReferenceBaseNode or ReferenceNode
+
 /** @module ReferenceNode **/
 
 /**
@@ -28,7 +30,7 @@ class ReferenceElementNode extends ArrayElementNode {
 	/**
 	 * Constructs a new reference element node.
 	 *
-	 * @param {Node} referenceNode - The reference node.
+	 * @param {Node?} referenceNode - The reference node.
 	 * @param {Node} indexNode - The index node that defines the element access.
 	 */
 	constructor( referenceNode, indexNode ) {
@@ -39,7 +41,7 @@ class ReferenceElementNode extends ArrayElementNode {
 		 * Similar to {@link module:ReferenceNode~ReferenceNode#reference}, an additional
 		 * property references to the current node.
 		 *
-		 * @type {Node}
+		 * @type {Node?}
 		 * @default null
 		 */
 		this.referenceNode = referenceNode;
@@ -180,7 +182,7 @@ class ReferenceNode extends Node {
 		this.name = null;
 
 		/**
-		 * Overwritten since velocity nodes are updated per object.
+		 * Overwritten since reference nodes are updated per object.
 		 *
 		 * @type {String}
 		 * @default 'object'

+ 167 - 3
src/nodes/accessors/StorageBufferNode.js

@@ -5,6 +5,39 @@ import { storageElement } from '../utils/StorageArrayElementNode.js';
 import { NodeAccess } from '../core/constants.js';
 import { getTypeFromLength } from '../core/NodeUtils.js';
 
+/** @module StorageBufferNode **/
+
+/**
+ * This node is used in context of compute shaders and allows to define a
+ * storage buffer for data. A typical workflow is to create instances of
+ * this node with the convenience functions `attributeArray()` or `instancedArray()`,
+ * setup up a compute shader that writes into the buffers and then convert
+ * the storage buffers to attributes for rendering.
+ *
+ * ```js
+ * const positionBuffer = instancedArray( particleCount, 'vec3' ); // the storage buffer node
+ *
+ * const computeInit = Fn( () => { // the compute shader
+ *
+ * 	const position = positionBuffer.element( instanceIndex );
+ *
+ * 	// compute position data
+ *
+ * 	position.x = 1;
+ * 	position.y = 1;
+ * 	position.z = 1;
+ *
+ * } )().compute( particleCount );
+ *
+ * const particleMaterial = new THREE.SpriteNodeMaterial();
+ * particleMaterial.positionNode = positionBuffer.toAttribute();
+ *
+ * renderer.computeAsync( computeInit );
+ *
+ * ```
+ *
+ * @augments BufferNode
+ */
 class StorageBufferNode extends BufferNode {
 
 	static get type() {
@@ -13,6 +46,13 @@ class StorageBufferNode extends BufferNode {
 
 	}
 
+	/**
+	 * Constructs a new storage buffer node.
+	 *
+	 * @param {StorageBufferAttribute|StorageInstancedBufferAttribute} value - The buffer data.
+	 * @param {String?} [bufferType=null] - The buffer type (e.g. `'vec3'`).
+	 * @param {Number} [bufferCount=0] - The buffer count.
+	 */
 	constructor( value, bufferType = null, bufferCount = 0 ) {
 
 		if ( bufferType === null && ( value.isStorageBufferAttribute || value.isStorageInstancedBufferAttribute ) ) {
@@ -24,17 +64,62 @@ class StorageBufferNode extends BufferNode {
 
 		super( value, bufferType, bufferCount );
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isStorageBufferNode = true;
 
+		/**
+		 * The acces type of the texture node.
+		 *
+		 * @type {String}
+		 * @default 'readWrite'
+		 */
 		this.access = NodeAccess.READ_WRITE;
+
+		/**
+		 * Whether the node is atmoic or not.
+		 *
+		 * @type {Boolean}
+		 * @default false
+		 */
 		this.isAtomic = false;
-		this.isPBO = false;
 
-		this.bufferCount = bufferCount;
+		/**
+		 * Whether the node represents a PBO or not.
+		 * Only relevant for WebGL.
+		 *
+		 * @type {Boolean}
+		 * @default false
+		 */
+		this.isPBO = false;
 
+		/**
+		 * A reference to the internal buffer attribute node.
+		 *
+		 * @type {BufferAttributeNode?}
+		 * @default null
+		 */
 		this._attribute = null;
+
+		/**
+		 * A reference to the internal varying node.
+		 *
+		 * @type {VaryingNode?}
+		 * @default null
+		 */
 		this._varying = null;
 
+		/**
+		 * `StorageBufferNode` sets this property to `true` by default.
+		 *
+		 * @type {Boolean}
+		 * @default true
+		 */
 		this.global = true;
 
 		if ( value.isStorageBufferAttribute !== true && value.isStorageInstancedBufferAttribute !== true ) {
@@ -48,6 +133,13 @@ class StorageBufferNode extends BufferNode {
 
 	}
 
+	/**
+	 * This method is overwritten since the buffer data might be shared
+	 * and thus the hash should be shared as well.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The hash.
+	 */
 	getHash( builder ) {
 
 		if ( this.bufferCount === 0 ) {
@@ -72,18 +164,36 @@ class StorageBufferNode extends BufferNode {
 
 	}
 
+	/**
+	 * Overwrites the default implementation to return a fixed value `'indirectStorageBuffer'` or `'storageBuffer'`.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The input type.
+	 */
 	getInputType( /*builder*/ ) {
 
 		return this.value.isIndirectStorageBufferAttribute ? 'indirectStorageBuffer' : 'storageBuffer';
 
 	}
 
+	/**
+	 * Enables element access with the given index node.
+	 *
+	 * @param {IndexNode} indexNode - The index node.
+	 * @return {StorageArrayElementNode} A node representing the element access.
+	 */
 	element( indexNode ) {
 
 		return storageElement( this, indexNode );
 
 	}
 
+	/**
+	 * Defines whether this node is a PBO or not. Only relevant for WebGL.
+	 *
+	 * @param {Boolean} value - The value so set.
+	 * @return {StorageBufferNode} A reference to this node.
+	 */
 	setPBO( value ) {
 
 		this.isPBO = value;
@@ -92,12 +202,23 @@ class StorageBufferNode extends BufferNode {
 
 	}
 
+	/**
+	 * Returns the `isPBO` value.
+	 *
+	 * @return {Boolean} Whether the node represents a PBO or not.
+	 */
 	getPBO() {
 
 		return this.isPBO;
 
 	}
 
+	/**
+	 * Defines the node access.
+	 *
+	 * @param {String} value - The node access.
+	 * @return {StorageBufferNode} A reference to this node.
+	 */
 	setAccess( value ) {
 
 		this.access = value;
@@ -106,12 +227,23 @@ class StorageBufferNode extends BufferNode {
 
 	}
 
+	/**
+	 * Convenience method for configuring a read-only node access.
+	 *
+	 * @return {StorageBufferNode} A reference to this node.
+	 */
 	toReadOnly() {
 
 		return this.setAccess( NodeAccess.READ_ONLY );
 
 	}
 
+	/**
+	 * Defines whether the node is amotic or not.
+	 *
+	 * @param {Boolean} value - The atomic flag.
+	 * @return {StorageBufferNode} A reference to this node.
+	 */
 	setAtomic( value ) {
 
 		this.isAtomic = value;
@@ -120,12 +252,22 @@ class StorageBufferNode extends BufferNode {
 
 	}
 
+	/**
+	 * Convenience method for making this node atmoic.
+	 *
+	 * @return {StorageBufferNode} A reference to this node.
+	 */
 	toAtomic() {
 
 		return this.setAtomic( true );
 
 	}
 
+	/**
+	 * Returns attribute data for this storage buffer node.
+	 *
+	 * @return {{attribute: BufferAttributeNode, varying: VaryingNode}} The attribute data.
+	 */
 	getAttributeData() {
 
 		if ( this._attribute === null ) {
@@ -142,6 +284,13 @@ class StorageBufferNode extends BufferNode {
 
 	}
 
+	/**
+	 * This method is overwritten since the node type from the availability of storage buffers
+	 * and the attribute data.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The node type.
+	 */
 	getNodeType( builder ) {
 
 		if ( builder.isAvailable( 'storageBuffer' ) || builder.isAvailable( 'indirectStorageBuffer' ) ) {
@@ -156,6 +305,12 @@ class StorageBufferNode extends BufferNode {
 
 	}
 
+	/**
+	 * Generates the code snippet of the storage buffer node.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The generated code snippet.
+	 */
 	generate( builder ) {
 
 		if ( builder.isAvailable( 'storageBuffer' ) || builder.isAvailable( 'indirectStorageBuffer' ) ) {
@@ -178,7 +333,16 @@ class StorageBufferNode extends BufferNode {
 
 export default StorageBufferNode;
 
-export const storage = ( value, type, count ) => nodeObject( new StorageBufferNode( value, type, count ) );
+/**
+ * TSL function for creating a storage buffer node.
+ *
+ * @function
+ * @param {StorageBufferAttribute|StorageInstancedBufferAttribute} value - The buffer data.
+ * @param {String?} [type=null] - The buffer type (e.g. `'vec3'`).
+ * @param {Number} [count=0] - The buffer count.
+ * @returns {StorageBufferNode}
+ */
+export const storage = ( value, type = null, count = 0 ) => nodeObject( new StorageBufferNode( value, type, count ) );
 
 export const storageObject = ( value, type, count ) => { // @deprecated, r171
 

+ 16 - 1
src/nodes/functions/material/getParallaxCorrectNormal.js

@@ -1,8 +1,23 @@
 import { positionWorld } from '../../accessors/Position.js';
 import { float, Fn, min, normalize, sub, vec3 } from '../../tsl/TSLBase.js';
 
-// https://devlog-martinsh.blogspot.com/2011/09/box-projected-cube-environment-mapping.html
+/** @module getParallaxCorrectNormal **/
 
+/**
+ * This computes a parallax corrected normal which is used for box-projected cube mapping (BPCEM).
+ *
+ * Reference: {@link https://devlog-martinsh.blogspot.com/2011/09/box-projected-cube-environment-mapping.html}
+ *
+ * ```js
+ * const uvNode = getParallaxCorrectNormal( reflectVector, vec3( 200, 100, 100 ), vec3( 0, - 50, 0 ) );
+ * material.envNode = pmremTexture( renderTarget.texture, uvNode );
+ * ```
+ * @function
+ * @param {Node<vec3>} normal - The normal to correct.
+ * @param {Node<vec3>} cubeSize - The cube size should reflect the size of the environment (BPCEM is usually applied in closed environments like rooms).
+ * @param {Node<vec3>} cubePos - The cube position.
+ * @return {Node<vec3>} The parallax corrected normal.
+ */
 const getParallaxCorrectNormal = /*@__PURE__*/ Fn( ( [ normal, cubeSize, cubePos ] ) => {
 
 	const nDir = normalize( normal ).toVar( 'nDir' );

+ 151 - 1
src/nodes/gpgpu/AtomicFunctionNode.js

@@ -1,6 +1,13 @@
 import TempNode from '../core/TempNode.js';
 import { nodeProxy } from '../tsl/TSLCore.js';
 
+/** @module AtomicFunctionNode **/
+
+/**
+ * TODO
+ *
+ * @augments TempNode
+ */
 class AtomicFunctionNode extends TempNode {
 
 	static get type() {
@@ -9,24 +16,68 @@ class AtomicFunctionNode extends TempNode {
 
 	}
 
+	/**
+	 * Constructs a new atomic function node.
+	 *
+	 * @param {String} method - TODO.
+	 * @param {Node} pointerNode - TODO.
+	 * @param {Node} valueNode - TODO.
+	 * @param {Node?} [storeNode=null] - TODO.
+	 */
 	constructor( method, pointerNode, valueNode, storeNode = null ) {
 
 		super( 'uint' );
 
+		/**
+		 * TODO
+		 *
+		 * @type {String}
+		 */
 		this.method = method;
 
+		/**
+		 * TODO
+		 *
+		 * @type {Node}
+		 */
 		this.pointerNode = pointerNode;
+
+		/**
+		 * TODO
+		 *
+		 * @type {Node}
+		 */
 		this.valueNode = valueNode;
+
+		/**
+		 * TODO
+		 *
+		 * @type {Node?}
+		 * @default null
+		 */
 		this.storeNode = storeNode;
 
 	}
 
+	/**
+	 * Overwrites the default implementation to return the type of
+	 * the pointer node.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The input type.
+	 */
 	getInputType( builder ) {
 
 		return this.pointerNode.getNodeType( builder );
 
 	}
 
+	/**
+	 * Overwritten since the node type is inferred from the input type.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The node type.
+	 */
 	getNodeType( builder ) {
 
 		return this.getInputType( builder );
@@ -78,9 +129,29 @@ AtomicFunctionNode.ATOMIC_XOR = 'atomicXor';
 
 export default AtomicFunctionNode;
 
+/**
+ * TSL function for creating an atomic function node.
+ *
+ * @function
+ * @param {String} method - TODO.
+ * @param {Node} pointerNode - TODO.
+ * @param {Node} valueNode - TODO.
+ * @param {Node?} [storeNode=null] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
 const atomicNode = nodeProxy( AtomicFunctionNode );
 
-export const atomicFunc = ( method, pointerNode, valueNode, storeNode ) => {
+/**
+ * TODO
+ *
+ * @function
+ * @param {String} method - TODO.
+ * @param {Node} pointerNode - TODO.
+ * @param {Node} valueNode - TODO.
+ * @param {Node?} [storeNode=null] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
+export const atomicFunc = ( method, pointerNode, valueNode, storeNode = null ) => {
 
 	const node = atomicNode( method, pointerNode, valueNode, storeNode );
 	node.append();
@@ -89,11 +160,90 @@ export const atomicFunc = ( method, pointerNode, valueNode, storeNode ) => {
 
 };
 
+/**
+ * TODO
+ *
+ * @function
+ * @param {Node} pointerNode - TODO.
+ * @param {Node} valueNode - TODO.
+ * @param {Node?} [storeNode=null] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
 export const atomicStore = ( pointerNode, valueNode, storeNode = null ) => atomicFunc( AtomicFunctionNode.ATOMIC_STORE, pointerNode, valueNode, storeNode );
+
+/**
+ * TODO
+ *
+ * @function
+ * @param {Node} pointerNode - TODO.
+ * @param {Node} valueNode - TODO.
+ * @param {Node?} [storeNode=null] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
 export const atomicAdd = ( pointerNode, valueNode, storeNode = null ) => atomicFunc( AtomicFunctionNode.ATOMIC_ADD, pointerNode, valueNode, storeNode );
+
+/**
+ * TODO
+ *
+ * @function
+ * @param {Node} pointerNode - TODO.
+ * @param {Node} valueNode - TODO.
+ * @param {Node?} [storeNode=null] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
 export const atomicSub = ( pointerNode, valueNode, storeNode = null ) => atomicFunc( AtomicFunctionNode.ATOMIC_SUB, pointerNode, valueNode, storeNode );
+
+/**
+ * TODO
+ *
+ * @function
+ * @param {Node} pointerNode - TODO.
+ * @param {Node} valueNode - TODO.
+ * @param {Node?} [storeNode=null] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
 export const atomicMax = ( pointerNode, valueNode, storeNode = null ) => atomicFunc( AtomicFunctionNode.ATOMIC_MAX, pointerNode, valueNode, storeNode );
+
+/**
+ * TODO
+ *
+ * @function
+ * @param {Node} pointerNode - TODO.
+ * @param {Node} valueNode - TODO.
+ * @param {Node?} [storeNode=null] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
 export const atomicMin = ( pointerNode, valueNode, storeNode = null ) => atomicFunc( AtomicFunctionNode.ATOMIC_MIN, pointerNode, valueNode, storeNode );
+
+/**
+ * TODO
+ *
+ * @function
+ * @param {Node} pointerNode - TODO.
+ * @param {Node} valueNode - TODO.
+ * @param {Node?} [storeNode=null] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
 export const atomicAnd = ( pointerNode, valueNode, storeNode = null ) => atomicFunc( AtomicFunctionNode.ATOMIC_AND, pointerNode, valueNode, storeNode );
+
+/**
+ * TODO
+ *
+ * @function
+ * @param {Node} pointerNode - TODO.
+ * @param {Node} valueNode - TODO.
+ * @param {Node?} [storeNode=null] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
 export const atomicOr = ( pointerNode, valueNode, storeNode = null ) => atomicFunc( AtomicFunctionNode.ATOMIC_OR, pointerNode, valueNode, storeNode );
+
+/**
+ * TODO
+ *
+ * @function
+ * @param {Node} pointerNode - TODO.
+ * @param {Node} valueNode - TODO.
+ * @param {Node?} [storeNode=null] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
 export const atomicXor = ( pointerNode, valueNode, storeNode = null ) => atomicFunc( AtomicFunctionNode.ATOMIC_XOR, pointerNode, valueNode, storeNode );

+ 39 - 0
src/nodes/gpgpu/BarrierNode.js

@@ -1,8 +1,20 @@
 import Node from '../core/Node.js';
 import { nodeProxy } from '../tsl/TSLCore.js';
 
+/** @module BarrierNode **/
+
+/**
+ * TODO
+ *
+ * @augments Node
+ */
 class BarrierNode extends Node {
 
+	/**
+	 * Constructs a new barrier node.
+	 *
+	 * @param {String} scope - The scope defines the behavior of the node.
+	 */
 	constructor( scope ) {
 
 		super();
@@ -32,9 +44,36 @@ class BarrierNode extends Node {
 
 export default BarrierNode;
 
+/**
+ * TSL function for creating a barrier node.
+ *
+ * @function
+ * @param {String} scope - The scope defines the behavior of the node..
+ * @returns {BarrierNode}
+ */
 const barrier = nodeProxy( BarrierNode );
 
+/**
+ * TSL function for creating a workgroup barrier.
+ *
+ * @function
+ * @returns {BarrierNode}
+ */
 export const workgroupBarrier = () => barrier( 'workgroup' ).append();
+
+/**
+ * TSL function for creating a storage barrier.
+ *
+ * @function
+ * @returns {BarrierNode}
+ */
 export const storageBarrier = () => barrier( 'storage' ).append();
+
+/**
+ * TSL function for creating a texture barrier.
+ *
+ * @function
+ * @returns {BarrierNode}
+ */
 export const textureBarrier = () => barrier( 'texture' ).append();
 

+ 83 - 0
src/nodes/gpgpu/ComputeBuiltinNode.js

@@ -1,6 +1,13 @@
 import Node from '../core/Node.js';
 import { nodeObject } from '../tsl/TSLBase.js';
 
+/** @module ComputeBuiltinNode **/
+
+/**
+ * TODO
+ *
+ * @augments Node
+ */
 class ComputeBuiltinNode extends Node {
 
 	static get type() {
@@ -9,26 +16,56 @@ class ComputeBuiltinNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a new compute builtin node.
+	 *
+	 * @param {String} builtinName - The built-in name.
+	 * @param {String} nodeType - The node type.
+	 */
 	constructor( builtinName, nodeType ) {
 
 		super( nodeType );
 
+		/**
+		 * The built-in name.
+		 *
+		 * @private
+		 * @type {String}
+		 */
 		this._builtinName = builtinName;
 
 	}
 
+	/**
+	 * This method is overwritten since hash is derived from the built-in name.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The hash.
+	 */
 	getHash( builder ) {
 
 		return this.getBuiltinName( builder );
 
 	}
 
+	/**
+	 * This method is overwritten since the node type is simply dervied from `nodeType`..
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The node type.
+	 */
 	getNodeType( /*builder*/ ) {
 
 		return this.nodeType;
 
 	}
 
+	/**
+	 * Sets the builtin name.
+	 *
+	 * @param {String} builtinName - The built-in name.
+	 * @return {ComputeBuiltinNode} A reference to this node.
+	 */
 	setBuiltinName( builtinName ) {
 
 		this._builtinName = builtinName;
@@ -37,12 +74,23 @@ class ComputeBuiltinNode extends Node {
 
 	}
 
+	/**
+	 * Returns the builtin name.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The builtin name.
+	 */
 	getBuiltinName( /*builder*/ ) {
 
 		return this._builtinName;
 
 	}
 
+	/**
+	 * Whether the current node builder has the builtin or not.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 */
 	hasBuiltin( builder ) {
 
 		builder.hasBuiltin( this._builtinName );
@@ -89,10 +137,45 @@ class ComputeBuiltinNode extends Node {
 
 export default ComputeBuiltinNode;
 
+/**
+ * TSL function for creating a compute builtin node.
+ *
+ * @function
+ * @param {String} name - The built-in name.
+ * @param {String} nodeType - The node type.
+ * @returns {ComputeBuiltinNode}
+ */
 const computeBuiltin = ( name, nodeType ) => nodeObject( new ComputeBuiltinNode( name, nodeType ) );
 
+/**
+ * TSL function for creating a `numWorkgroups` builtin node.
+ *
+ * @function
+ * @returns {ComputeBuiltinNode<uvec3>}
+ */
 export const numWorkgroups = /*@__PURE__*/ computeBuiltin( 'numWorkgroups', 'uvec3' );
+
+/**
+ * TSL function for creating a `workgroupId` builtin node.
+ *
+ * @function
+ * @returns {ComputeBuiltinNode<uvec3>}
+ */
 export const workgroupId = /*@__PURE__*/ computeBuiltin( 'workgroupId', 'uvec3' );
+
+/**
+ * TSL function for creating a `localId` builtin node.
+ *
+ * @function
+ * @returns {ComputeBuiltinNode<uvec3>}
+ */
 export const localId = /*@__PURE__*/ computeBuiltin( 'localId', 'uvec3' );
+
+/**
+ * TSL function for creating a `subgroupSize` builtin node.
+ *
+ * @function
+ * @returns {ComputeBuiltinNode<uint>}
+ */
 export const subgroupSize = /*@__PURE__*/ computeBuiltin( 'subgroupSize', 'uint' );
 

+ 88 - 6
src/nodes/gpgpu/ComputeNode.js

@@ -2,6 +2,13 @@ import Node from '../core/Node.js';
 import { NodeUpdateType } from '../core/constants.js';
 import { addMethodChaining, nodeObject } from '../tsl/TSLCore.js';
 
+/** @module ComputeNode **/
+
+/**
+ * TODO
+ *
+ * @augments Node
+ */
 class ComputeNode extends Node {
 
 	static get type() {
@@ -10,39 +17,94 @@ class ComputeNode extends Node {
 
 	}
 
+	/**
+	 * Constructs a new compute node.
+	 *
+	 * @param {Node} computeNode - TODO
+	 * @param {Number} count - TODO.
+	 * @param {Array<Number>} [workgroupSize=[64]] - TODO.
+	 */
 	constructor( computeNode, count, workgroupSize = [ 64 ] ) {
 
 		super( 'void' );
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isComputeNode = true;
 
+		/**
+		 * TODO
+		 *
+		 * @type {Node}
+		 */
 		this.computeNode = computeNode;
 
+		/**
+		 * TODO
+		 *
+		 * @type {Number}
+		 */
 		this.count = count;
+
+		/**
+		 * TODO
+		 *
+		 * @type {Array<Number>}
+		 * @default [64]
+		 */
 		this.workgroupSize = workgroupSize;
+
+		/**
+		 * TODO
+		 *
+		 * @type {Number}
+		 */
 		this.dispatchCount = 0;
 
+		/**
+		 * TODO
+		 *
+		 * @type {Number}
+		 */
 		this.version = 1;
+
+		/**
+		 * The `updateBeforeType` is set to `NodeUpdateType.OBJECT` since {@link ComputeNode#updateBefore}
+		 * is executed once per object by default.
+		 *
+		 * @type {String}
+		 * @default 'object'
+		 */
 		this.updateBeforeType = NodeUpdateType.OBJECT;
 
+		/**
+		 * TODO
+		 *
+		 * @type {Function}
+		 */
 		this.onInitFunction = null;
 
 		this.updateDispatchCount();
 
 	}
 
+	/**
+	 * Executes the `dispose` event for this noode.
+	 */
 	dispose() {
 
 		this.dispatchEvent( { type: 'dispose' } );
 
 	}
 
-	set needsUpdate( value ) {
-
-		if ( value === true ) this.version ++;
-
-	}
-
+	/**
+	 * TODO
+	 */
 	updateDispatchCount() {
 
 		const { count, workgroupSize } = this;
@@ -56,6 +118,12 @@ class ComputeNode extends Node {
 
 	}
 
+	/**
+	 * TODO
+	 *
+	 * @param {Function} callback - TODO.
+	 * @return {ComputeNode} A reference to this node.
+	 */
 	onInit( callback ) {
 
 		this.onInitFunction = callback;
@@ -64,6 +132,11 @@ class ComputeNode extends Node {
 
 	}
 
+	/**
+	 * The method execute the compute for this node.
+	 *
+	 * @param {NodeFrame} frame - A reference to the current node frame.
+	 */
 	updateBefore( { renderer } ) {
 
 		renderer.compute( this );
@@ -92,6 +165,15 @@ class ComputeNode extends Node {
 
 export default ComputeNode;
 
+/**
+ * TSL function for creating a compute node.
+ *
+ * @function
+ * @param {Node} node - TODO
+ * @param {Number} count - TODO.
+ * @param {Array<Number>} [workgroupSize=[64]] - TODO.
+ * @returns {AtomicFunctionNode}
+ */
 export const compute = ( node, count, workgroupSize ) => nodeObject( new ComputeNode( nodeObject( node ), count, workgroupSize ) );
 
 addMethodChaining( 'compute', compute );

+ 89 - 7
src/nodes/gpgpu/WorkgroupInfoNode.js

@@ -2,12 +2,32 @@ import ArrayElementNode from '../utils/ArrayElementNode.js';
 import { nodeObject } from '../tsl/TSLCore.js';
 import Node from '../core/Node.js';
 
+/** @module WorkgroupInfoNode **/
+
+/**
+ * TODO
+ *
+ * @augments ArrayElementNode
+ */
 class WorkgroupInfoElementNode extends ArrayElementNode {
 
+	/**
+	 * Constructs a new workgroup info element node.
+	 *
+	 * @param {Node} workgroupInfoNode - The workgroup info node.
+	 * @param {Node} indexNode - The index node that defines the element access.
+	 */
 	constructor( workgroupInfoNode, indexNode ) {
 
 		super( workgroupInfoNode, indexNode );
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isWorkgroupInfoElementNode = true;
 
 	}
@@ -35,22 +55,63 @@ class WorkgroupInfoElementNode extends ArrayElementNode {
 
 }
 
-
+/**
+ * TODO
+ *
+ * @augments Node
+ */
 class WorkgroupInfoNode extends Node {
 
+	/**
+	 * Constructs a new workgroup info node.
+	 *
+	 * @param {String} scope - TODO.
+	 * @param {String} bufferType - The buffer type.
+	 * @param {Number} [bufferCount=0] - The buffer count.
+	 */
 	constructor( scope, bufferType, bufferCount = 0 ) {
 
 		super( bufferType );
 
+		/**
+		 * The buffer type.
+		 *
+		 * @type {String}
+		 */
 		this.bufferType = bufferType;
+
+		/**
+		 * The buffer count.
+		 *
+		 * @type {Number}
+		 * @default 0
+		 */
 		this.bufferCount = bufferCount;
 
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {Boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.isWorkgroupInfoNode = true;
 
+		/**
+		 * TODO.
+		 *
+		 * @type {String}
+		 */
 		this.scope = scope;
 
 	}
 
+	/**
+	 * Sets the name/label of this node.
+	 *
+	 * @param {String} name - The name to set.
+	 * @return {WorkgroupInfoNode} A reference to this node.
+	 */
 	label( name ) {
 
 		this.name = name;
@@ -59,12 +120,12 @@ class WorkgroupInfoNode extends Node {
 
 	}
 
-	getHash() {
-
-		return this.uuid;
-
-	}
-
+	/**
+	 * Sets the scope of this node.
+	 *
+	 * @param {String} scope - The scope to set.
+	 * @return {WorkgroupInfoNode} A reference to this node.
+	 */
 	setScope( scope ) {
 
 		this.scope = scope;
@@ -73,12 +134,25 @@ class WorkgroupInfoNode extends Node {
 
 	}
 
+	/**
+	 * Overwrites the default implementation since the input type
+	 * is inferred from the scope.
+	 *
+	 * @param {NodeBuilder} builder - The current node builder.
+	 * @return {String} The input type.
+	 */
 	getInputType( /*builder*/ ) {
 
 		return `${this.scope}Array`;
 
 	}
 
+	/**
+	 * This method can be used to access elements via an index node.
+	 *
+	 * @param {IndexNode} indexNode - indexNode.
+	 * @return {WorkgroupInfoElementNode} A reference to an element.
+	 */
 	element( indexNode ) {
 
 		return nodeObject( new WorkgroupInfoElementNode( this, indexNode ) );
@@ -95,6 +169,14 @@ class WorkgroupInfoNode extends Node {
 
 export default WorkgroupInfoNode;
 
+/**
+ * TSL function for creating a workgroup info node.
+ *
+ * @function
+ * @param {String} type - The buffer type.
+ * @param {Number} [count=0] - The buffer count.
+ * @returns {WorkgroupInfoNode}
+ */
 export const workgroupArray = ( type, count ) => nodeObject( new WorkgroupInfoNode( 'Workgroup', type, count ) );
 
 

粤ICP备19079148号