Skip to content

Commit 0f523ac

Browse files
authored
Node: Document more modules. (#30123)
* Node: Document more modules. * Node: Document more modules. * Exampels: Clean up.
1 parent ef5be21 commit 0f523ac

13 files changed

+1102
-38
lines changed

examples/webgpu_compute_sort_bitonic.html

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
<script type="module">
5656

5757
import * as THREE from 'three';
58-
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';
58+
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';
5959

6060
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
6161

@@ -141,17 +141,17 @@
141141

142142
const nextAlgoBuffer = new THREE.StorageInstancedBufferAttribute( new Uint32Array( 1 ).fill( forceGlobalSwap ? StepType.FLIP_GLOBAL : StepType.FLIP_LOCAL ), 1 );
143143

144-
const nextAlgoStorage = storageObject( nextAlgoBuffer, 'uint', nextAlgoBuffer.count ).label( 'NextAlgo' );
144+
const nextAlgoStorage = storage( nextAlgoBuffer, 'uint', nextAlgoBuffer.count ).setPBO( true ).label( 'NextAlgo' );
145145

146146
const nextBlockHeightBuffer = new THREE.StorageInstancedBufferAttribute( new Uint32Array( 1 ).fill( 2 ), 1 );
147-
const nextBlockHeightStorage = storageObject( nextBlockHeightBuffer, 'uint', nextBlockHeightBuffer.count ).label( 'NextBlockHeight' );
148-
const nextBlockHeightRead = storageObject( nextBlockHeightBuffer, 'uint', nextBlockHeightBuffer.count ).label( 'NextBlockHeight' ).toReadOnly();
147+
const nextBlockHeightStorage = storage( nextBlockHeightBuffer, 'uint', nextBlockHeightBuffer.count ).setPBO( true ).label( 'NextBlockHeight' );
148+
const nextBlockHeightRead = storage( nextBlockHeightBuffer, 'uint', nextBlockHeightBuffer.count ).setPBO( true ).label( 'NextBlockHeight' ).toReadOnly();
149149

150150
const highestBlockHeightBuffer = new THREE.StorageInstancedBufferAttribute( new Uint32Array( 1 ).fill( 2 ), 1 );
151-
const highestBlockHeightStorage = storageObject( highestBlockHeightBuffer, 'uint', highestBlockHeightBuffer.count ).label( 'HighestBlockHeight' );
151+
const highestBlockHeightStorage = storage( highestBlockHeightBuffer, 'uint', highestBlockHeightBuffer.count ).setPBO( true ).label( 'HighestBlockHeight' );
152152

153153
const counterBuffer = new THREE.StorageBufferAttribute( 1, 1 );
154-
const counterStorage = storageObject( counterBuffer, 'uint', counterBuffer.count ).toAtomic().label( 'Counter' );
154+
const counterStorage = storage( counterBuffer, 'uint', counterBuffer.count ).setPBO( true ).toAtomic().label( 'Counter' );
155155

156156
const array = new Uint32Array( Array.from( { length: size }, ( _, i ) => {
157157

@@ -179,11 +179,11 @@
179179
randomizeDataArray();
180180

181181
const currentElementsBuffer = new THREE.StorageInstancedBufferAttribute( array, 1 );
182-
const currentElementsStorage = storageObject( currentElementsBuffer, 'uint', size ).label( 'Elements' );
182+
const currentElementsStorage = storage( currentElementsBuffer, 'uint', size ).setPBO( true ).label( 'Elements' );
183183
const tempBuffer = new THREE.StorageInstancedBufferAttribute( array, 1 );
184-
const tempStorage = storageObject( tempBuffer, 'uint', size ).label( 'Temp' );
184+
const tempStorage = storage( tempBuffer, 'uint', size ).setPBO( true ).label( 'Temp' );
185185
const randomizedElementsBuffer = new THREE.StorageInstancedBufferAttribute( size, 1 );
186-
const randomizedElementsStorage = storageObject( randomizedElementsBuffer, 'uint', size ).label( 'RandomizedElements' );
186+
const randomizedElementsStorage = storage( randomizedElementsBuffer, 'uint', size ).setPBO( true ).label( 'RandomizedElements' );
187187

188188
const getFlipIndices = ( index, blockHeight ) => {
189189

src/nodes/accessors/Arrays.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ import StorageBufferAttribute from '../../renderers/common/StorageBufferAttribut
33
import { storage } from './StorageBufferNode.js';
44
import { getLengthFromType } from '../core/NodeUtils.js';
55

6+
/** @module Arrays **/
7+
8+
/**
9+
* TSL function for creating a storage buffer node with a configured `StorageBufferAttribute`.
10+
*
11+
* @function
12+
* @param {Number} count - The data count.
13+
* @param {String} [type='float'] - The data type.
14+
* @returns {StorageBufferNode}
15+
*/
616
export const attributeArray = ( count, type = 'float' ) => {
717

818
const itemSize = getLengthFromType( type );
@@ -14,7 +24,14 @@ export const attributeArray = ( count, type = 'float' ) => {
1424

1525
};
1626

17-
27+
/**
28+
* TSL function for creating a storage buffer node with a configured `StorageInstancedBufferAttribute`.
29+
*
30+
* @function
31+
* @param {Number} count - The data count.
32+
* @param {String} [type='float'] - The data type.
33+
* @returns {StorageBufferNode}
34+
*/
1835
export const instancedArray = ( count, type = 'float' ) => {
1936

2037
const itemSize = getLengthFromType( type );

src/nodes/accessors/BufferAttributeNode.js

Lines changed: 178 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,30 @@ import { InterleavedBufferAttribute } from '../../core/InterleavedBufferAttribut
66
import { InterleavedBuffer } from '../../core/InterleavedBuffer.js';
77
import { StaticDrawUsage, DynamicDrawUsage } from '../../constants.js';
88

9+
/** @module BufferAttributeNode **/
10+
11+
/**
12+
* In earlier `three.js` versions it was only possible to define attribute data
13+
* on geometry level. With `BufferAttributeNode`, it is also possible to do this
14+
* on the node level.
15+
* ```js
16+
* const geometry = new THREE.PlaneGeometry();
17+
* const positionAttribute = geometry.getAttribute( 'position' );
18+
*
19+
* const colors = [];
20+
* for ( let i = 0; i < position.count; i ++ ) {
21+
* colors.push( 1, 0, 0 );
22+
* }
23+
*
24+
* material.colorNode = bufferAttribute( new THREE.Float32BufferAttribute( colors, 3 ) );
25+
* ```
26+
* This new approach is especially interesting when geometry data are generated via
27+
* compute shaders. The below line converts a storage buffer into an attribute.
28+
* ```js
29+
* material.positionNode = positionBuffer.toAttribute();
30+
* ```
31+
* @augments InputNode
32+
*/
933
class BufferAttributeNode extends InputNode {
1034

1135
static get type() {
@@ -14,21 +38,82 @@ class BufferAttributeNode extends InputNode {
1438

1539
}
1640

41+
/**
42+
* Constructs a new buffer attribute node.
43+
*
44+
* @param {BufferAttribute|InterleavedBuffer|TypedArray} value - The attribute data.
45+
* @param {String?} [bufferType=null] - The buffer type (e.g. `'vec3'`).
46+
* @param {Number} [bufferStride=0] - The buffer stride.
47+
* @param {Number} [bufferOffset=0] - The buffer offset.
48+
*/
1749
constructor( value, bufferType = null, bufferStride = 0, bufferOffset = 0 ) {
1850

1951
super( value, bufferType );
2052

53+
/**
54+
* This flag can be used for type testing.
55+
*
56+
* @type {Boolean}
57+
* @readonly
58+
* @default true
59+
*/
2160
this.isBufferNode = true;
2261

62+
/**
63+
* The buffer type (e.g. `'vec3'`).
64+
*
65+
* @type {String}
66+
* @default null
67+
*/
2368
this.bufferType = bufferType;
69+
70+
/**
71+
* The buffer stride.
72+
*
73+
* @type {Number}
74+
* @default 0
75+
*/
2476
this.bufferStride = bufferStride;
77+
78+
/**
79+
* The buffer offset.
80+
*
81+
* @type {Number}
82+
* @default 0
83+
*/
2584
this.bufferOffset = bufferOffset;
2685

86+
/**
87+
* The usage property. Set this to `THREE.DynamicDrawUsage` via `.setUsage()`,
88+
* if you are planning to update the attribute data per frame.
89+
*
90+
* @type {Number}
91+
* @default StaticDrawUsage
92+
*/
2793
this.usage = StaticDrawUsage;
94+
95+
/**
96+
* Whether the attribute is instanced or not.
97+
*
98+
* @type {Boolean}
99+
* @default false
100+
*/
28101
this.instanced = false;
29102

103+
/**
104+
* A reference to the buffer attribute.
105+
*
106+
* @type {BufferAttribute?}
107+
* @default null
108+
*/
30109
this.attribute = null;
31110

111+
/**
112+
* `BufferAttributeNode` sets this property to `true` by default.
113+
*
114+
* @type {Boolean}
115+
* @default true
116+
*/
32117
this.global = true;
33118

34119
if ( value && value.isBufferAttribute === true ) {
@@ -41,6 +126,13 @@ class BufferAttributeNode extends InputNode {
41126

42127
}
43128

129+
/**
130+
* This method is overwritten since the attribute data might be shared
131+
* and thus the hash should be shared as well.
132+
*
133+
* @param {NodeBuilder} builder - The current node builder.
134+
* @return {String} The hash.
135+
*/
44136
getHash( builder ) {
45137

46138
if ( this.bufferStride === 0 && this.bufferOffset === 0 ) {
@@ -65,6 +157,13 @@ class BufferAttributeNode extends InputNode {
65157

66158
}
67159

160+
/**
161+
* This method is overwritten since the node type is inferred from
162+
* the buffer attribute.
163+
*
164+
* @param {NodeBuilder} builder - The current node builder.
165+
* @return {String} The node type.
166+
*/
68167
getNodeType( builder ) {
69168

70169
if ( this.bufferType === null ) {
@@ -77,6 +176,13 @@ class BufferAttributeNode extends InputNode {
77176

78177
}
79178

179+
/**
180+
* Depending on which value was passed to the node, `setup()` behaves
181+
* differently. If no instance of `BufferAttribute` was passed, the method
182+
* creates an internal attribute and configures it respectively.
183+
*
184+
* @param {NodeBuilder} builder - The current node builder.
185+
*/
80186
setup( builder ) {
81187

82188
if ( this.attribute !== null ) return;
@@ -97,6 +203,12 @@ class BufferAttributeNode extends InputNode {
97203

98204
}
99205

206+
/**
207+
* Generates the code snippet of the buffer attribute node.
208+
*
209+
* @param {NodeBuilder} builder - The current node builder.
210+
* @return {String} The generated code snippet.
211+
*/
100212
generate( builder ) {
101213

102214
const nodeType = this.getNodeType( builder );
@@ -124,12 +236,24 @@ class BufferAttributeNode extends InputNode {
124236

125237
}
126238

239+
/**
240+
* Overwrites the default implementation to return a fixed value `'bufferAttribute'`.
241+
*
242+
* @param {NodeBuilder} builder - The current node builder.
243+
* @return {String} The input type.
244+
*/
127245
getInputType( /*builder*/ ) {
128246

129247
return 'bufferAttribute';
130248

131249
}
132250

251+
/**
252+
* Sets the `usage` property to the given value.
253+
*
254+
* @param {Number} value - The usage to set.
255+
* @return {BufferAttributeNode} A reference to this node.
256+
*/
133257
setUsage( value ) {
134258

135259
this.usage = value;
@@ -144,6 +268,12 @@ class BufferAttributeNode extends InputNode {
144268

145269
}
146270

271+
/**
272+
* Sets the `instanced` property to the given value.
273+
*
274+
* @param {Number} value - The value to set.
275+
* @return {BufferAttributeNode} A reference to this node.
276+
*/
147277
setInstanced( value ) {
148278

149279
this.instanced = value;
@@ -156,10 +286,53 @@ class BufferAttributeNode extends InputNode {
156286

157287
export default BufferAttributeNode;
158288

159-
export const bufferAttribute = ( array, type, stride, offset ) => nodeObject( new BufferAttributeNode( array, type, stride, offset ) );
160-
export const dynamicBufferAttribute = ( array, type, stride, offset ) => bufferAttribute( array, type, stride, offset ).setUsage( DynamicDrawUsage );
161-
162-
export const instancedBufferAttribute = ( array, type, stride, offset ) => bufferAttribute( array, type, stride, offset ).setInstanced( true );
163-
export const instancedDynamicBufferAttribute = ( array, type, stride, offset ) => dynamicBufferAttribute( array, type, stride, offset ).setInstanced( true );
289+
/**
290+
* TSL function for creating a buffer attribute node.
291+
*
292+
* @function
293+
* @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data.
294+
* @param {String?} [type=null] - The buffer type (e.g. `'vec3'`).
295+
* @param {Number} [stride=0] - The buffer stride.
296+
* @param {Number} [offset=0] - The buffer offset.
297+
* @returns {BufferAttributeNode}
298+
*/
299+
export const bufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => nodeObject( new BufferAttributeNode( array, type, stride, offset ) );
300+
301+
/**
302+
* TSL function for creating a buffer attribute node but with dynamic draw usage.
303+
* Use this function if attribute data are updated per frame.
304+
*
305+
* @function
306+
* @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data.
307+
* @param {String?} [type=null] - The buffer type (e.g. `'vec3'`).
308+
* @param {Number} [stride=0] - The buffer stride.
309+
* @param {Number} [offset=0] - The buffer offset.
310+
* @returns {BufferAttributeNode}
311+
*/
312+
export const dynamicBufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => bufferAttribute( array, type, stride, offset ).setUsage( DynamicDrawUsage );
313+
314+
/**
315+
* TSL function for creating a buffer attribute node but with enabled instancing
316+
*
317+
* @function
318+
* @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data.
319+
* @param {String?} [type=null] - The buffer type (e.g. `'vec3'`).
320+
* @param {Number} [stride=0] - The buffer stride.
321+
* @param {Number} [offset=0] - The buffer offset.
322+
* @returns {BufferAttributeNode}
323+
*/
324+
export const instancedBufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => bufferAttribute( array, type, stride, offset ).setInstanced( true );
325+
326+
/**
327+
* TSL function for creating a buffer attribute node but with dynamic draw usage and enabled instancing
328+
*
329+
* @function
330+
* @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data.
331+
* @param {String?} [type=null] - The buffer type (e.g. `'vec3'`).
332+
* @param {Number} [stride=0] - The buffer stride.
333+
* @param {Number} [offset=0] - The buffer offset.
334+
* @returns {BufferAttributeNode}
335+
*/
336+
export const instancedDynamicBufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => dynamicBufferAttribute( array, type, stride, offset ).setInstanced( true );
164337

165338
addMethodChaining( 'toAttribute', ( bufferNode ) => bufferAttribute( bufferNode.value ) );

0 commit comments

Comments
 (0)