浏览代码

TSL: `uniforms` (#27706)

* remove unnecessary code

* TSL: Add uniforms
sunag 1 年之前
父节点
当前提交
d0ee260c95

+ 1 - 0
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';

+ 140 - 0
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 );

+ 6 - 4
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 );
 
 		}
 

+ 1 - 11
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 }` );
 
 			}