Browse Source

NodeMaterial: Arrays of uniforms (#22497)

* reuse type variable

* cleanup

* NodeMaterial: ArrayInput support
sunag 3 years ago
parent
commit
540c0e1550

+ 23 - 0
examples/jsm/renderers/nodes/core/ArrayInputNode.js

@@ -0,0 +1,23 @@
+import InputNode from './InputNode.js';
+
+class ArrayInputNode extends InputNode {
+
+	constructor( value = [] ) {
+
+		super();
+
+		this.value = value;
+
+	}
+
+	getType( builder ) {
+
+		return this.value[ 0 ].getType( builder );
+
+	}
+
+}
+
+ArrayInputNode.prototype.isArrayInputNode = true;
+
+export default ArrayInputNode;

+ 8 - 2
examples/jsm/renderers/nodes/core/FunctionNode.js

@@ -105,9 +105,15 @@ class FunctionNode extends CodeNode {
 				}
 				}
 
 
 				const type = propsMatches[ i ++ ][ 0 ];
 				const type = propsMatches[ i ++ ][ 0 ];
+
+				let count = Number.parseInt( propsMatches[ i ][ 0 ] );
+
+				if ( Number.isNaN( count ) === false ) i ++;
+				else count = 0;
+
 				const name = propsMatches[ i ++ ][ 0 ];
 				const name = propsMatches[ i ++ ][ 0 ];
 
 
-				inputs.push( new NodeFunctionInput( type, name, qualifier, isConst ) );
+				inputs.push( new NodeFunctionInput( type, name, qualifier, isConst, count ) );
 
 
 			}
 			}
 
 
@@ -135,7 +141,7 @@ class FunctionNode extends CodeNode {
 
 
 	}
 	}
 
 
-	call( parameters = null ) {
+	call( parameters = {} ) {
 
 
 		return new FunctionCallNode( this, parameters );
 		return new FunctionCallNode( this, parameters );
 
 

+ 1 - 1
examples/jsm/renderers/nodes/core/InputNode.js

@@ -40,7 +40,7 @@ class InputNode extends Node {
 
 
 		} else {
 		} else {
 
 
-			const nodeUniform = builder.getUniformFromNode( this, builder.shaderStage, this.getType( builder ) );
+			const nodeUniform = builder.getUniformFromNode( this, builder.shaderStage, type );
 			const propertyName = builder.getPropertyName( nodeUniform );
 			const propertyName = builder.getPropertyName( nodeUniform );
 
 
 			return builder.format( propertyName, type, output );
 			return builder.format( propertyName, type, output );

+ 12 - 18
examples/jsm/renderers/nodes/core/NodeBuilder.js

@@ -102,12 +102,6 @@ class NodeBuilder {
 
 
 	}
 	}
 
 
-	getPMREM( texture ) {
-
-		console.warn( 'Abstract function.' );
-
-	}
-
 	getConst( type, value ) {
 	getConst( type, value ) {
 
 
 		if ( type === 'float' ) return value + ( value % 1 ? '' : '.0' );
 		if ( type === 'float' ) return value + ( value % 1 ? '' : '.0' );
@@ -588,26 +582,26 @@ class NodeBuilder {
 			case 'float to vec4' : return `vec4( vec3( ${snippet} ), 1.0 )`;
 			case 'float to vec4' : return `vec4( vec3( ${snippet} ), 1.0 )`;
 
 
 			case 'vec2 to float' : return `${snippet}.x`;
 			case 'vec2 to float' : return `${snippet}.x`;
-			case 'vec2 to vec3' : return `vec3( ${snippet}, 0.0 )`;
-			case 'vec2 to vec4' : return `vec4( ${snippet}.xy, 0.0, 1.0 )`;
+			case 'vec2 to vec3'  : return `vec3( ${snippet}, 0.0 )`;
+			case 'vec2 to vec4'  : return `vec4( ${snippet}.xy, 0.0, 1.0 )`;
 
 
 			case 'vec3 to float' : return `${snippet}.x`;
 			case 'vec3 to float' : return `${snippet}.x`;
-			case 'vec3 to vec2' : return `${snippet}.xy`;
-			case 'vec3 to vec4' : return `vec4( ${snippet}, 1.0 )`;
+			case 'vec3 to vec2'  : return `${snippet}.xy`;
+			case 'vec3 to vec4'  : return `vec4( ${snippet}, 1.0 )`;
 
 
 			case 'vec4 to float' : return `${snippet}.x`;
 			case 'vec4 to float' : return `${snippet}.x`;
-			case 'vec4 to vec2' : return `${snippet}.xy`;
-			case 'vec4 to vec3' : return `${snippet}.xyz`;
+			case 'vec4 to vec2'  : return `${snippet}.xy`;
+			case 'vec4 to vec3'  : return `${snippet}.xyz`;
 
 
 			case 'mat3 to float' : return `( ${snippet} * vec3( 1.0 ) ).x`;
 			case 'mat3 to float' : return `( ${snippet} * vec3( 1.0 ) ).x`;
-			case 'mat3 to vec2' : return `( ${snippet} * vec3( 1.0 ) ).xy`;
-			case 'mat3 to vec3' : return `( ${snippet} * vec3( 1.0 ) ).xyz`;
-			case 'mat3 to vec4' : return `vec4( ${snippet} * vec3( 1.0 ), 1.0 )`;
+			case 'mat3 to vec2'  : return `( ${snippet} * vec3( 1.0 ) ).xy`;
+			case 'mat3 to vec3'  : return `( ${snippet} * vec3( 1.0 ) ).xyz`;
+			case 'mat3 to vec4'  : return `vec4( ${snippet} * vec3( 1.0 ), 1.0 )`;
 
 
 			case 'mat4 to float' : return `( ${snippet} * vec4( 1.0 ) ).x`;
 			case 'mat4 to float' : return `( ${snippet} * vec4( 1.0 ) ).x`;
-			case 'mat4 to vec2' : return `( ${snippet} * vec4( 1.0 ) ).xy`;
-			case 'mat4 to vec3' : return `( ${snippet} * vec4( 1.0 ) ).xyz`;
-			case 'mat4 to vec4' : return `( ${snippet} * vec4( 1.0 ) )`;
+			case 'mat4 to vec2'  : return `( ${snippet} * vec4( 1.0 ) ).xy`;
+			case 'mat4 to vec3'  : return `( ${snippet} * vec4( 1.0 ) ).xyz`;
+			case 'mat4 to vec4'  : return `( ${snippet} * vec4( 1.0 ) )`;
 
 
 		}
 		}
 
 

+ 2 - 1
examples/jsm/renderers/nodes/core/NodeFunctionInput.js

@@ -1,11 +1,12 @@
 class NodeFunctionInput {
 class NodeFunctionInput {
 
 
-	constructor( type, name, qualifier = '', isConst = false ) {
+	constructor( type, name, qualifier = '', isConst = false, count = 0 ) {
 
 
 		this.type = type;
 		this.type = type;
 		this.name = name;
 		this.name = name;
 		this.qualifier = qualifier;
 		this.qualifier = qualifier;
 		this.isConst = isConst;
 		this.isConst = isConst;
+		this.count = count;
 
 
 		Object.defineProperty( this, 'isNodeFunction', { value: true } );
 		Object.defineProperty( this, 'isNodeFunction', { value: true } );
 
 

+ 13 - 6
examples/jsm/renderers/webgpu/WebGPUBufferUtils.js

@@ -8,19 +8,26 @@ function getFloatLength( floatLength ) {
 
 
 }
 }
 
 
-function getVectorLength( count, vectorLength ) {
+function getVectorLength( count, vectorLength = 4 ) {
 
 
-	const strideLength = 4;
-
-	vectorLength = vectorLength + ( ( strideLength - ( vectorLength % strideLength ) ) % strideLength );
+	const strideLength = getStrideLength( vectorLength );
 
 
-	const floatLength = vectorLength * count;
+	const floatLength = strideLength * count;
 
 
 	return getFloatLength( floatLength );
 	return getFloatLength( floatLength );
 
 
 }
 }
 
 
+function getStrideLength( vectorLength ) {
+
+	const strideLength = 4;
+
+	return vectorLength + ( ( strideLength - ( vectorLength % strideLength ) ) % strideLength );
+
+}
+
 export {
 export {
 	getFloatLength,
 	getFloatLength,
-	getVectorLength
+	getVectorLength,
+	getStrideLength
 };
 };

+ 42 - 24
examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js

@@ -6,6 +6,8 @@ import {
 import WebGPUNodeSampler from './WebGPUNodeSampler.js';
 import WebGPUNodeSampler from './WebGPUNodeSampler.js';
 import { WebGPUNodeSampledTexture } from './WebGPUNodeSampledTexture.js';
 import { WebGPUNodeSampledTexture } from './WebGPUNodeSampledTexture.js';
 
 
+import { getVectorLength, getStrideLength } from '../WebGPUBufferUtils.js';
+
 import NodeSlot from '../../nodes/core/NodeSlot.js';
 import NodeSlot from '../../nodes/core/NodeSlot.js';
 import VarNode from '../../nodes/core/VarNode.js';
 import VarNode from '../../nodes/core/VarNode.js';
 import NodeBuilder from '../../nodes/core/NodeBuilder.js';
 import NodeBuilder from '../../nodes/core/NodeBuilder.js';
@@ -245,7 +247,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 				bindings.splice( index, 0, sampler, texture );
 				bindings.splice( index, 0, sampler, texture );
 
 
-				uniformGPU = { sampler, texture };
+				uniformGPU = [ sampler, texture ];
 
 
 			} else {
 			} else {
 
 
@@ -261,41 +263,33 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 				}
 				}
 
 
-				if ( type === 'float' ) {
-
-					uniformGPU = new FloatNodeUniform( uniformNode );
-
-				} else if ( type === 'vec2' ) {
-
-					uniformGPU = new Vector2NodeUniform( uniformNode );
-
-				} else if ( type === 'vec3' ) {
+				if ( node.isArrayInputNode === true ) {
 
 
-					uniformGPU = new Vector3NodeUniform( uniformNode );
+					uniformGPU = [];
 
 
-				} else if ( type === 'vec4' ) {
+					console.log( );
 
 
-					uniformGPU = new Vector4NodeUniform( uniformNode );
+					for ( const inputNode of node.value ) {
 
 
-				} else if ( type === 'color' ) {
+						const uniformNodeGPU = this._getNodeUniform( inputNode, type );
 
 
-					uniformGPU = new ColorNodeUniform( uniformNode );
+						// fit bounds to buffer
+						uniformNodeGPU.boundary = getVectorLength( uniformNodeGPU.itemSize );
+						uniformNodeGPU.itemSize = getStrideLength( uniformNodeGPU.itemSize );
 
 
-				} else if ( type === 'mat3' ) {
+						uniformsGroup.addUniform( uniformNodeGPU );
 
 
-					uniformGPU = new Matrix3NodeUniform( uniformNode );
+						uniformGPU.push( uniformNodeGPU );
 
 
-				} else if ( type === 'mat4' ) {
-
-					uniformGPU = new Matrix4NodeUniform( uniformNode );
+					}
 
 
 				} else {
 				} else {
 
 
-					throw new Error( `Uniform "${type}" not declared.` );
+					uniformGPU = this._getNodeUniform( uniformNode, type );
 
 
-				}
+					uniformsGroup.addUniform( uniformGPU );
 
 
-				uniformsGroup.addUniform( uniformGPU );
+				}
 
 
 			}
 			}
 
 
@@ -375,7 +369,17 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 				const vectorType = this.getVectorType( uniform.type );
 				const vectorType = this.getVectorType( uniform.type );
 
 
-				groupSnippet += `uniform ${vectorType} ${uniform.name}; `;
+				if ( Array.isArray( uniform.value ) === true ) {
+
+					const length = uniform.value.length;
+
+					groupSnippet += `uniform ${vectorType}[ ${length} ] ${uniform.name}; `;
+
+				} else {
+
+					groupSnippet += `uniform ${vectorType} ${uniform.name}; `;
+
+				}
 
 
 			}
 			}
 
 
@@ -427,6 +431,20 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 	}
 	}
 
 
+	_getNodeUniform( uniformNode, type ) {
+
+		if ( type === 'float' ) return new FloatNodeUniform( uniformNode );
+		if ( type === 'vec2' ) return new Vector2NodeUniform( uniformNode );
+		if ( type === 'vec3' ) return new Vector3NodeUniform( uniformNode );
+		if ( type === 'vec4' ) return new Vector4NodeUniform( uniformNode );
+		if ( type === 'color' ) return new ColorNodeUniform( uniformNode );
+		if ( type === 'mat3' ) return new Matrix3NodeUniform( uniformNode );
+		if ( type === 'mat4' ) return new Matrix4NodeUniform( uniformNode );
+
+		throw new Error( `Uniform "${type}" not declared.` );
+
+	}
+
 }
 }
 
 
 export default WebGPUNodeBuilder;
 export default WebGPUNodeBuilder;