From 686774f79f0b62721c39d2d635b79f27652751aa Mon Sep 17 00:00:00 2001 From: sunag Date: Wed, 7 Feb 2024 23:50:19 -0300 Subject: [PATCH 1/2] remove unnecessary code --- .../jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js b/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js index 7e1fca4741b1d0..a86e35580374dc 100644 --- a/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +++ b/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js @@ -783,17 +783,7 @@ ${ flowData.code } snippets: [] } ); - if ( Array.isArray( uniform.value ) === true ) { - - const length = uniform.value.length; - - group.snippets.push( `uniform ${vectorType}[ ${length} ] ${uniform.name}` ); - - } else { - - group.snippets.push( `\t${uniform.name} : ${ vectorType}` ); - - } + group.snippets.push( `\t${ uniform.name } : ${ vectorType }` ); } From 2e259903b230bdf767277de12b12479c7289423e Mon Sep 17 00:00:00 2001 From: sunag Date: Wed, 7 Feb 2024 23:52:03 -0300 Subject: [PATCH 2/2] TSL: Add uniforms --- examples/jsm/nodes/Nodes.js | 1 + examples/jsm/nodes/accessors/UniformsNode.js | 140 ++++++++++++++++++ .../jsm/renderers/common/UniformsGroup.js | 10 +- 3 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 examples/jsm/nodes/accessors/UniformsNode.js diff --git a/examples/jsm/nodes/Nodes.js b/examples/jsm/nodes/Nodes.js index 236b46ae1faf9c..1e92c22bd033f7 100644 --- a/examples/jsm/nodes/Nodes.js +++ b/examples/jsm/nodes/Nodes.js @@ -77,6 +77,7 @@ export * from './shadernode/ShaderNode.js'; // accessors export { TBNViewMatrix } from './accessors/AccessorsUtils.js'; +export { default as UniformsNode, uniforms } from './accessors/UniformsNode.js'; export { default as BitangentNode, bitangentGeometry, bitangentLocal, bitangentView, bitangentWorld, transformedBitangentView, transformedBitangentWorld } from './accessors/BitangentNode.js'; export { default as BufferAttributeNode, bufferAttribute, dynamicBufferAttribute, instancedBufferAttribute, instancedDynamicBufferAttribute } from './accessors/BufferAttributeNode.js'; export { default as BufferNode, buffer } from './accessors/BufferNode.js'; diff --git a/examples/jsm/nodes/accessors/UniformsNode.js b/examples/jsm/nodes/accessors/UniformsNode.js new file mode 100644 index 00000000000000..2e6ef2366acc94 --- /dev/null +++ b/examples/jsm/nodes/accessors/UniformsNode.js @@ -0,0 +1,140 @@ +import { addNodeClass } from '../core/Node.js'; +import { nodeObject } from '../shadernode/ShaderNode.js'; +import { NodeUpdateType } from '../core/constants.js'; +import { getValueType } from '../core/NodeUtils.js'; +import ArrayElementNode from '../utils/ArrayElementNode.js'; +import BufferNode from './BufferNode.js'; + +class UniformsElementNode extends ArrayElementNode { + + constructor( arrayBuffer, indexNode ) { + + super( arrayBuffer, indexNode ); + + this.isArrayBufferElementNode = true; + + } + + getNodeType( builder ) { + + return this.node.getElementType( builder ); + + } + + generate( builder ) { + + const snippet = super.generate( builder ); + const type = this.getNodeType(); + + return builder.format( snippet, 'vec4', type ); + + } + +} + +class UniformsNode extends BufferNode { + + constructor( value, elementType = null ) { + + super( null, 'vec4' ); + + this.array = value; + this.elementType = elementType; + + this._elementType = null; + this._elementLength = 0; + + this.updateBeforeType = NodeUpdateType.RENDER; + + this.isArrayBufferNode = true; + + } + + getElementType() { + + return this.elementType || this._elementType; + + } + + getElementLength() { + + return this._elementLength; + + } + + updateBefore( /*frame*/ ) { + + const { array, value } = this; + + const elementLength = this.getElementLength(); + const elementType = this.getElementType(); + + if ( elementLength === 1 ) { + + for ( let i = 0; i < array.length; i ++ ) { + + const index = i * 4; + + value[ index ] = array[ i ]; + + } + + } else if ( elementType === 'color' ) { + + for ( let i = 0; i < array.length; i ++ ) { + + const index = i * 4; + const vector = array[ i ]; + + value[ index ] = vector.r; + value[ index + 1 ] = vector.g; + value[ index + 2 ] = vector.b || 0; + //value[ index + 3 ] = vector.a || 0; + + } + + } else { + + for ( let i = 0; i < array.length; i ++ ) { + + const index = i * 4; + const vector = array[ i ]; + + value[ index ] = vector.x; + value[ index + 1 ] = vector.y; + value[ index + 2 ] = vector.z || 0; + value[ index + 3 ] = vector.w || 0; + + } + + } + + } + + setup( builder ) { + + const length = this.array.length; + + this._elementType = this.elementType === null ? getValueType( this.array[ 0 ] ) : this.elementType; + this._elementLength = builder.getTypeLength( this._elementType ); + + this.value = new Float32Array( length * 4 ); + this.bufferCount = length; + + return super.setup( builder ); + + } + + element( indexNode ) { + + return nodeObject( new UniformsElementNode( this, nodeObject( indexNode ) ) ); + + } + +} + +export default UniformsNode; + +export const uniforms = ( values, nodeType ) => nodeObject( new UniformsNode( values, nodeType ) ); + +addNodeClass( 'UniformsNode', UniformsNode ); diff --git a/examples/jsm/renderers/common/UniformsGroup.js b/examples/jsm/renderers/common/UniformsGroup.js index 58450ebb0f98df..21bb2cd33010f4 100644 --- a/examples/jsm/renderers/common/UniformsGroup.js +++ b/examples/jsm/renderers/common/UniformsGroup.js @@ -63,6 +63,8 @@ class UniformsGroup extends UniformBuffer { const uniform = this.uniforms[ i ]; + const { boundary, itemSize } = uniform; + // offset within a single chunk in bytes const chunkOffset = offset % GPU_CHUNK_BYTES; @@ -70,23 +72,23 @@ class UniformsGroup extends UniformBuffer { // conformance tests - if ( chunkOffset !== 0 && ( remainingSizeInChunk - uniform.boundary ) < 0 ) { + if ( chunkOffset !== 0 && ( remainingSizeInChunk - boundary ) < 0 ) { // check for chunk overflow offset += ( GPU_CHUNK_BYTES - chunkOffset ); - } else if ( chunkOffset % uniform.boundary !== 0 ) { + } else if ( chunkOffset % boundary !== 0 ) { // check for correct alignment - offset += ( chunkOffset % uniform.boundary ); + offset += ( chunkOffset % boundary ); } uniform.offset = ( offset / this.bytesPerElement ); - offset += ( uniform.itemSize * this.bytesPerElement ); + offset += ( itemSize * this.bytesPerElement ); }