@@ -6,6 +6,30 @@ import { InterleavedBufferAttribute } from '../../core/InterleavedBufferAttribut
66import { InterleavedBuffer } from '../../core/InterleavedBuffer.js' ;
77import { 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+ */
933class 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
157287export 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
165338addMethodChaining ( 'toAttribute' , ( bufferNode ) => bufferAttribute ( bufferNode . value ) ) ;
0 commit comments