Browse Source

WVPNode and updates

sunag 4 years ago
parent
commit
d217cfaf82
27 changed files with 679 additions and 388 deletions
  1. 83 0
      examples/jsm/renderers/nodes/accessors/CameraNode.js
  2. 49 0
      examples/jsm/renderers/nodes/accessors/ModelNode.js
  3. 39 0
      examples/jsm/renderers/nodes/accessors/PositionNode.js
  4. 2 19
      examples/jsm/renderers/nodes/accessors/UVNode.js
  5. 32 0
      examples/jsm/renderers/nodes/accessors/WVPNode.js
  6. 29 21
      examples/jsm/renderers/nodes/core/AttributeNode.js
  7. 9 1
      examples/jsm/renderers/nodes/core/Node.js
  8. 14 0
      examples/jsm/renderers/nodes/core/NodeAttribute.js
  9. 123 65
      examples/jsm/renderers/nodes/core/NodeBuilder.js
  10. 14 2
      examples/jsm/renderers/nodes/core/NodeFrame.js
  11. 2 0
      examples/jsm/renderers/nodes/core/NodeUniform.js
  12. 15 0
      examples/jsm/renderers/nodes/core/NodeVary.js
  13. 36 0
      examples/jsm/renderers/nodes/core/VaryNode.js
  14. 8 2
      examples/jsm/renderers/nodes/core/constants.js
  15. 16 0
      examples/jsm/renderers/nodes/inputs/Matrix3Node.js
  16. 16 0
      examples/jsm/renderers/nodes/inputs/Matrix4Node.js
  17. 2 1
      examples/jsm/renderers/nodes/inputs/Vector3Node.js
  18. 2 1
      examples/jsm/renderers/nodes/inputs/Vector4Node.js
  19. 47 6
      examples/jsm/renderers/nodes/math/OperatorNode.js
  20. 2 1
      examples/jsm/renderers/nodes/utils/TimerNode.js
  21. 2 0
      examples/jsm/renderers/webgpu/WebGPUBinding.js
  22. 7 70
      examples/jsm/renderers/webgpu/WebGPUBindings.js
  23. 21 126
      examples/jsm/renderers/webgpu/nodes/ShaderLib.js
  24. 81 53
      examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js
  25. 0 9
      examples/jsm/renderers/webgpu/nodes/WebGPUNodeUniformsGroup.js
  26. 8 5
      examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js
  27. 20 6
      examples/webgpu_sandbox.html

+ 83 - 0
examples/jsm/renderers/nodes/accessors/CameraNode.js

@@ -0,0 +1,83 @@
+import Node from '../core/Node.js';
+import Vector3Node from '../inputs/Vector3Node.js';
+import Matrix4Node from '../inputs/Matrix4Node.js';
+import { NodeUpdateType } from '../core/constants.js';
+
+class CameraNode extends Node {
+
+	static POSITION = 'position';
+	static PROJECTION = 'projection';
+	static VIEW = 'view';
+
+	constructor( scope = CameraNode.POSITION ) {
+
+		super();
+
+		this.updateType = NodeUpdateType.Frame;
+
+		this.scope = scope;
+		
+		this.inputNode = null;
+
+	}
+
+	getType() {
+
+		if ( this.scope === CameraNode.PROJECTION || this.scope === CameraNode.VIEW ) {
+			
+			return 'mat4';
+			
+		}
+
+		return 'vec3';
+
+	}
+	
+	update( frame ) {
+
+		const camera = frame.camera;
+		const inputNode = this.inputNode;
+
+		if ( this.scope === CameraNode.PROJECTION ) {
+			
+			inputNode.value = camera.projectionMatrix;
+			
+		} else if ( this.scope === CameraNode.VIEW ) {
+			
+			inputNode.value = camera.matrixWorldInverse;
+			
+		} else if ( this.scope === CameraNode.POSITION ) {
+			
+			camera.getWorldPosition( inputNode.value );
+			
+		}
+
+	}
+
+	generate( builder, output ) {
+
+		const nodeData = builder.getDataFromNode( this );
+
+		if ( this.initialized !== true ) {
+			
+			if ( this.scope === CameraNode.PROJECTION || this.scope === CameraNode.VIEW ) {
+				
+				this.inputNode = new Matrix4Node( null );
+				
+			} else {
+				
+				this.inputNode = new Vector3Node();
+				
+			}
+			
+			nodeData.initialized = true;
+			
+		}
+
+		return this.inputNode.build( builder, output );
+
+	}
+
+}
+
+export default CameraNode;

+ 49 - 0
examples/jsm/renderers/nodes/accessors/ModelNode.js

@@ -0,0 +1,49 @@
+import Node from '../core/Node.js';
+import Vector3Node from '../inputs/Vector3Node.js';
+import Matrix4Node from '../inputs/Matrix4Node.js';
+import { NodeUpdateType } from '../core/constants.js';
+
+class ModelNode extends Node {
+
+	static VIEW = 'view';
+
+	constructor( scope = ModelNode.VIEW ) {
+
+		super( 'mat4' );
+
+		this.scope = scope;
+
+		this.updateType = NodeUpdateType.Object;
+
+		this.inputNode = null;
+
+	}
+
+	update( frame ) {
+
+		const object = frame.object;
+		const inputNode = this.inputNode;
+
+		inputNode.value = object.modelViewMatrix;
+
+	}
+
+	generate( builder, output ) {
+
+		const nodeData = builder.getDataFromNode( this );
+
+		if ( this.initialized !== true ) {
+			
+			this.inputNode = new Matrix4Node( null );
+
+			nodeData.initialized = true;
+			
+		}
+
+		return this.inputNode.build( builder, output );
+
+	}
+
+}
+
+export default ModelNode;

+ 39 - 0
examples/jsm/renderers/nodes/accessors/PositionNode.js

@@ -0,0 +1,39 @@
+import Node from '../core/Node.js';
+import AttributeNode from '../core/AttributeNode.js';
+
+class PositionNode extends Node {
+
+	static LOCAL = 'position';
+
+	constructor( scope = PositionNode.POSITION ) {
+
+		super( 'vec3' );
+
+		this.scope = scope;
+
+	}
+
+	generate( builder, output ) {
+
+		const type = this.getType( builder );
+		const nodeData = builder.getDataFromNode( this, builder.shaderStage );
+
+		let positionNode = nodeData.positionNode;
+
+		if ( positionNode === undefined ) {
+			
+			positionNode = new AttributeNode( 'position', 'vec3' );
+			
+			nodeData.positionNode = positionNode;
+
+		}
+
+		const positionSnipped = positionNode.build( builder, type );
+
+		return builder.format( positionSnipped, type, output );
+
+	}
+
+}
+
+export default PositionNode;

+ 2 - 19
examples/jsm/renderers/nodes/accessors/UVNode.js

@@ -4,32 +4,15 @@ class UVNode extends AttributeNode {
 
 
 	constructor( index = 0 ) {
 	constructor( index = 0 ) {
 
 
-		super( 'vec2' );
+		super( null, 'vec2' );
 
 
 		this.index = index;
 		this.index = index;
 
 
 	}
 	}
 
 
-	getIndexProperty( prefix ) {
-
-		return prefix + ( this.index > 0 ? this.index + 1 : '' );
-
-	}
-
 	getAttributeName( /*builder*/ ) {
 	getAttributeName( /*builder*/ ) {
 
 
-		return this.getIndexProperty( 'uv' );
-
-	}
-
-	getAttributeProperty( builder ) {
-
-		// customize 'uv' property
-		const property = this.getIndexProperty( 'vUv' );
-
-		this.setAttributeProperty( property );
-
-		return super.getAttributeProperty( builder );
+		return 'uv' + ( this.index > 0 ? this.index + 1 : '' );
 
 
 	}
 	}
 
 

+ 32 - 0
examples/jsm/renderers/nodes/accessors/WVPNode.js

@@ -0,0 +1,32 @@
+import Node from '../core/Node.js';
+import CameraNode from '../accessors/CameraNode.js';
+import ModelNode from '../accessors/ModelNode.js';
+import OperatorNode from '../math/OperatorNode.js';
+import PositionNode from '../accessors/PositionNode.js';
+
+class WVPNode extends Node {
+
+	constructor( position = new PositionNode() ) {
+
+		super('vec4');
+
+		this.position = position;
+
+		this._wvpMatrix = new OperatorNode( '*', new CameraNode( CameraNode.PROJECTION ), new ModelNode( ModelNode.VIEW ) );
+
+	}
+
+	generate( builder, output ) {
+
+		const type = this.getType( builder );
+
+		const wvpSnipped = this._wvpMatrix.build( builder );
+		const positionSnipped = this.position.build( builder, 'vec3' );
+
+		return builder.format( `( ${wvpSnipped} * vec4( ${positionSnipped}, 1.0 ) )`, type, output );
+
+	}
+
+}
+
+export default WVPNode;

+ 29 - 21
examples/jsm/renderers/nodes/core/AttributeNode.js

@@ -2,12 +2,11 @@ import Node from './Node.js';
 
 
 class AttributeNode extends Node {
 class AttributeNode extends Node {
 
 
-	constructor( type, name = null, property = null ) {
+	constructor( name, type ) {
 
 
 		super( type );
 		super( type );
 
 
 		this.name = name;
 		this.name = name;
-		this.property = property;
 
 
 	}
 	}
 
 
@@ -25,27 +24,36 @@ class AttributeNode extends Node {
 
 
 	}
 	}
 
 
-	setAttributeProperty( name ) {
-
-		this.property = name;
-
-		return this;
-
-	}
-
-	getAttributeProperty( builder ) {
-
-		const attribute = builder.getAttribute( this.getType( builder ), this.getAttributeName( builder ), this.property );
-
-		return attribute.property;
-
-	}
-
 	generate( builder, output ) {
 	generate( builder, output ) {
 
 
-		const attributeProperty = this.getAttributeProperty( builder );
-
-		return builder.format( attributeProperty, this.getType( builder ), output );
+		const attributeName = this.getAttributeName( builder );
+		const attributeType = this.getType( builder );
+
+		const attribute = builder.getAttribute( attributeName, attributeType );
+
+		if ( builder.isShaderStage( 'vertex' ) ) {
+		
+			return builder.format( attributeName, attributeType, output );
+			
+		} else {
+			
+			const nodeData = builder.getDataFromNode( this, builder.shaderStage );
+			
+			let nodeVary = nodeData.varyNode;
+			
+			if ( nodeVary === undefined ) {
+				
+				nodeVary = builder.getVaryFromNode( this, attributeType, attributeName );
+				
+				nodeData.nodeVary = nodeVary;
+				
+			}
+			
+			const varyName = builder.getPropertyName( nodeVary );
+			
+			return builder.format( varyName, attributeType, output );
+			
+		}
 
 
 	}
 	}
 
 

+ 9 - 1
examples/jsm/renderers/nodes/core/Node.js

@@ -1,15 +1,23 @@
+import { NodeUpdateType } from './constants.js';
+
 class Node {
 class Node {
 
 
 	constructor( type = null ) {
 	constructor( type = null ) {
 
 
 		this.type = type;
 		this.type = type;
 
 
-		this.needsUpdate = false;
+		this.updateType = NodeUpdateType.None;
 
 
 		Object.defineProperty( this, 'isNode', { value: true } );
 		Object.defineProperty( this, 'isNode', { value: true } );
 
 
 	}
 	}
 
 
+	getUpdateType( /*builder*/ ) {
+
+		return this.updateType;
+
+	}
+
 	getType( /*builder*/ ) {
 	getType( /*builder*/ ) {
 
 
 		return this.type;
 		return this.type;

+ 14 - 0
examples/jsm/renderers/nodes/core/NodeAttribute.js

@@ -0,0 +1,14 @@
+class NodeAttribute {
+
+	constructor( name, type ) {
+
+		this.name = name;
+		this.type = type;
+
+		Object.defineProperty( this, 'isNodeAttribute', { value: true } );
+
+	}
+
+}
+
+export default NodeAttribute;

+ 123 - 65
examples/jsm/renderers/nodes/core/NodeBuilder.js

@@ -1,4 +1,7 @@
 import NodeUniform from './NodeUniform.js';
 import NodeUniform from './NodeUniform.js';
+import NodeAttribute from './NodeAttribute.js';
+import NodeVary from './NodeVary.js';
+import { NodeUpdateType } from './constants.js';
 
 
 class NodeBuilder {
 class NodeBuilder {
 
 
@@ -16,8 +19,8 @@ class NodeBuilder {
 		this.slots = { vertex: [], fragment: [] };
 		this.slots = { vertex: [], fragment: [] };
 		this.defines = { vertex: {}, fragment: {} };
 		this.defines = { vertex: {}, fragment: {} };
 		this.uniforms = { vertex: [], fragment: [] };
 		this.uniforms = { vertex: [], fragment: [] };
-		this.attributes = {};
-		this.attributeCount = 0;
+		this.attributes = [];
+		this.varys = [];
 
 
 		this.nodesData = new WeakMap();
 		this.nodesData = new WeakMap();
 
 
@@ -29,7 +32,9 @@ class NodeBuilder {
 
 
 		if ( this.nodes.indexOf( node ) === - 1 ) {
 		if ( this.nodes.indexOf( node ) === - 1 ) {
 
 
-			if ( node.needsUpdate === true ) {
+			const updateType = node.getUpdateType( this );
+
+			if ( updateType !== NodeUpdateType.None ) {
 
 
 				this.updateNodes.push( node );
 				this.updateNodes.push( node );
 
 
@@ -71,41 +76,56 @@ class NodeBuilder {
 
 
 	}
 	}
 
 
-	getAttribute( type, name, property = null ) {
-
-		let attribute = this.attributes[ name ];
-
-		if ( attribute === undefined ) {
+	getAttribute( name, type ) {
 
 
-			const index = this.attributeCount ++;
+		const attributes = this.attributes;
 
 
-			if ( property === null ) {
-
-				property = `node_A${index}`;
+		// find attribute
 
 
+		for ( const attribute of attributes ) {
+			
+			if ( attribute.name === name ) {
+				
+				return attribute;
+				
 			}
 			}
+			
+		}
 
 
-			attribute = {
-				type,
-				name,
-				index,
-				property
-			};
+		// create a new if no exist
 
 
-			this.attributes[ name ] = attribute;
+		const attribute = new NodeAttribute( name, type );
 
 
-		}
+		attributes.push( attribute );
 
 
 		return attribute;
 		return attribute;
 
 
 	}
 	}
 
 
-	getPropertyName( nodeUniform ) {
+	getPropertyName( node ) {
 
 
-		return nodeUniform.name;
+		return node.name;
 
 
 	}
 	}
 
 
+	isVector( type ) {
+		
+		return /vec\d/.test( type );
+		
+	}
+
+	isMatrix( type ) {
+		
+		return /mat\d/.test( type );
+		
+	}
+	
+	isShaderStage( shaderStage ) {
+		
+		return this.shaderStage === shaderStage;
+		
+	}
+	
 	getVectorType( type ) {
 	getVectorType( type ) {
 
 
 		if ( type === 'color' ) return 'vec3';
 		if ( type === 'color' ) return 'vec3';
@@ -178,6 +198,29 @@ class NodeBuilder {
 
 
 	}
 	}
 
 
+	getVaryFromNode( node, type, value ) {
+		
+		const nodeData = this.getDataFromNode( node );
+
+		let nodeVary = nodeData.vary;
+
+		if ( nodeVary === undefined ) {
+
+			const varys = this.varys;
+			const index = varys.length;
+
+			nodeVary = new NodeVary( 'nodeV' + index, type, value );
+
+			varys.push( nodeVary );
+
+			nodeData.vary = nodeVary;
+
+		}
+
+		return nodeVary;
+		
+	}
+
 	/*
 	/*
 	analyzeNode( node ) {
 	analyzeNode( node ) {
 
 
@@ -221,51 +264,22 @@ class NodeBuilder {
 
 
 
 
 	}
 	}
-
-	getUniformsHeaderSnippet( shaderStage ) {
-
-		const uniforms = this.uniforms[ shaderStage ];
-
-		let snippet = '';
-
-		for ( const uniform of uniforms ) {
-
-			snippet += `${uniform.type} ${uniform.name}; `;
-
-		}
-
-		return snippet;
-
+	
+	getVarysHeaderSnippet( /*shaderStage*/ ) {
+		
+		
+		
+	}
+	
+	getVarysBodySnippet( /*shaderStage*/ ) {
+		
+		
+		
 	}
 	}
 
 
-	format( snippet, fromType, toType ) {
-
-		fromType = this.getVectorType( fromType );
-		toType = this.getVectorType( toType );
-
-		const typeToType = `${fromType} to ${toType}`;
-
-		switch ( typeToType ) {
-
-			case 'float to vec2' : return `vec2( ${snippet} )`;
-			case 'float to vec3' : return `vec3( ${snippet} )`;
-			case 'float to vec4' : return `vec4( vec3( ${snippet} ), 1.0 )`;
-
-			case 'vec2 to float' : return `${snippet}.x`;
-			case 'vec2 to vec3' : return `vec3( ${snippet}.x, ${snippet}.y, 0.0 )`;
-			case 'vec2 to vec4' : return `vec4( ${snippet}.x, ${snippet}.y, 0.0, 1.0 )`;
-
-			case 'vec3 to float' : return `${snippet}.x`;
-			case 'vec3 to vec2' : return `${snippet}.xy`;
-			case 'vec3 to vec4' : return `vec4( ${snippet}.x, ${snippet}.y, ${snippet}.z, 1.0 )`;
-
-			case 'vec4 to float' : return `${snippet}.x`;
-			case 'vec4 to vec2' : return `${snippet}.xy`;
-			case 'vec4 to vec3' : return `${snippet}.xyz`;
-
-		}
+	getUniformsHeaderSnippet( shaderStage ) {
 
 
-		return snippet;
+		
 
 
 	}
 	}
 
 
@@ -302,7 +316,9 @@ class NodeBuilder {
 
 
 			this.define( shaderStage, 'NODE_HEADER_UNIFORMS', this.getUniformsHeaderSnippet( shaderStage ) );
 			this.define( shaderStage, 'NODE_HEADER_UNIFORMS', this.getUniformsHeaderSnippet( shaderStage ) );
 			this.define( shaderStage, 'NODE_HEADER_ATTRIBUTES', this.getAttributesHeaderSnippet( shaderStage ) );
 			this.define( shaderStage, 'NODE_HEADER_ATTRIBUTES', this.getAttributesHeaderSnippet( shaderStage ) );
-			this.define( shaderStage, 'NODE_BODY_ATTRIBUTES', this.getAttributesBodySnippet( shaderStage ) );
+			this.define( shaderStage, 'NODE_HEADER_VARYS', this.getVarysHeaderSnippet( shaderStage ) );
+			
+			this.define( shaderStage, 'NODE_BODY_VARYS', this.getVarysBodySnippet( shaderStage ) );
 
 
 			shaderData[ shaderStage ] = this._buildDefines( shaderStage );
 			shaderData[ shaderStage ] = this._buildDefines( shaderStage );
 
 
@@ -314,6 +330,48 @@ class NodeBuilder {
 		return this;
 		return this;
 
 
 	}
 	}
+	
+	format( snippet, fromType, toType ) {
+
+		fromType = this.getVectorType( fromType );
+		toType = this.getVectorType( toType );
+
+		const typeToType = `${fromType} to ${toType}`;
+
+		switch ( typeToType ) {
+
+			case 'float to vec2' : return `vec2( ${snippet} )`;
+			case 'float to vec3' : return `vec3( ${snippet} )`;
+			case 'float to vec4' : return `vec4( vec3( ${snippet} ), 1.0 )`;
+
+			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 'vec3 to float' : return `${snippet}.x`;
+			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 vec2'  : return `${snippet}.xy`;
+			case 'vec4 to vec3'  : return `${snippet}.xyz`;
+
+			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 '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 ) )`;
+
+		}
+
+		return snippet;
+
+	}
+
 
 
 }
 }
 
 

+ 14 - 2
examples/jsm/renderers/nodes/core/NodeFrame.js

@@ -1,3 +1,5 @@
+import { NodeUpdateType } from './constants.js';
+
 class NodeFrame {
 class NodeFrame {
 
 
 	constructor() {
 	constructor() {
@@ -13,14 +15,24 @@ class NodeFrame {
 
 
 		this.renderer = null;
 		this.renderer = null;
 		this.material = null;
 		this.material = null;
+		this.camera = null;
+		this.object = null;
 
 
 	}
 	}
 
 
 	updateNode( node ) {
 	updateNode( node ) {
 
 
-		if ( this.updateMap.get( node ) !== this.frameId ) {
+		if ( node.updateType === NodeUpdateType.Frame ) {
+
+			if ( this.updateMap.get( node ) !== this.frameId ) {
+
+				this.updateMap.set( node, this.frameId );
+
+				node.update( this );
+
+			}
 
 
-			this.updateMap.set( node, this.frameId );
+		} else if ( node.updateType === NodeUpdateType.Object ) {
 
 
 			node.update( this );
 			node.update( this );
 
 

+ 2 - 0
examples/jsm/renderers/nodes/core/NodeUniform.js

@@ -7,6 +7,8 @@ class NodeUniform {
 		this.node = node;
 		this.node = node;
 		this.needsUpdate = needsUpdate;
 		this.needsUpdate = needsUpdate;
 
 
+		Object.defineProperty( this, 'isNodeUniform', { value: true } );
+
 	}
 	}
 
 
 	get value() {
 	get value() {

+ 15 - 0
examples/jsm/renderers/nodes/core/NodeVary.js

@@ -0,0 +1,15 @@
+class NodeVary {
+
+	constructor( name, type, value ) {
+
+		this.name = name;
+		this.type = type;
+		this.value = value;
+
+		Object.defineProperty( this, 'isNodeVary', { value: true } );
+
+	}
+
+}
+
+export default NodeVary;

+ 36 - 0
examples/jsm/renderers/nodes/core/VaryNode.js

@@ -0,0 +1,36 @@
+import Node from './Node.js';
+
+class VaryNode extends Node {
+
+	constructor( value ) {
+
+		super();
+
+		this.value = value;
+
+	}
+
+	getType( builder ) {
+		
+		// VaryNode is auto type
+		
+		return this.value.getType( builder );
+		
+	}
+
+	generate( builder, output ) {
+
+		const type = this.getType( builder );
+
+		const value = this.value.build( builder, type );
+
+		const nodeVary = builder.getVaryFromNode( this, type, value );
+		const propertyName = builder.getPropertyName( nodeVary );
+
+		return builder.format( propertyName, type, output );
+
+	}
+
+}
+
+export default VaryNode;

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

@@ -1,8 +1,14 @@
+export const NodeUpdateType = {
+	None: 'none',
+	Frame: 'frame',
+	Object: 'object'
+}
+
 export const NodeType = {
 export const NodeType = {
 	Float: 'float',
 	Float: 'float',
 	Vector2: 'vec2',
 	Vector2: 'vec2',
 	Vector3: 'vec3',
 	Vector3: 'vec3',
 	Vector4: 'vec4',
 	Vector4: 'vec4',
-	Matrix3: 'matrix3',
-	Matrix4: 'matrix4'
+	Matrix3: 'mat3',
+	Matrix4: 'mat4'
 };
 };

+ 16 - 0
examples/jsm/renderers/nodes/inputs/Matrix3Node.js

@@ -0,0 +1,16 @@
+import InputNode from '../core/InputNode.js';
+import { Matrix3 } from '../../../../../build/three.module.js';
+
+class Matrix3Node extends InputNode {
+
+	constructor( value = new Matrix3() ) {
+
+		super( 'mat3' );
+
+		this.value = value;
+
+	}
+
+}
+
+export default Matrix3Node;

+ 16 - 0
examples/jsm/renderers/nodes/inputs/Matrix4Node.js

@@ -0,0 +1,16 @@
+import InputNode from '../core/InputNode.js';
+import { Matrix4 } from '../../../../../build/three.module.js';
+
+class Matrix4Node extends InputNode {
+
+	constructor( value = new Matrix4() ) {
+
+		super( 'mat4' );
+
+		this.value = value;
+
+	}
+
+}
+
+export default Matrix4Node;

+ 2 - 1
examples/jsm/renderers/nodes/inputs/Vector3Node.js

@@ -1,8 +1,9 @@
 import InputNode from '../core/InputNode.js';
 import InputNode from '../core/InputNode.js';
+import { Vector3 } from '../../../../../build/three.module.js';
 
 
 class Vector3Node extends InputNode {
 class Vector3Node extends InputNode {
 
 
-	constructor( value ) {
+	constructor( value = new Vector3() ) {
 
 
 		super( 'vec3' );
 		super( 'vec3' );
 
 

+ 2 - 1
examples/jsm/renderers/nodes/inputs/Vector4Node.js

@@ -1,8 +1,9 @@
 import InputNode from '../core/InputNode.js';
 import InputNode from '../core/InputNode.js';
+import { Vector4 } from '../../../../../build/three.module.js';
 
 
 class Vector4Node extends InputNode {
 class Vector4Node extends InputNode {
 
 
-	constructor( value ) {
+	constructor( value = new Vector4() ) {
 
 
 		super( 'vec4' );
 		super( 'vec4' );
 
 

+ 47 - 6
examples/jsm/renderers/nodes/math/OperatorNode.js

@@ -18,9 +18,21 @@ class OperatorNode extends Node {
 		const typeA = this.a.getType( builder );
 		const typeA = this.a.getType( builder );
 		const typeB = this.b.getType( builder );
 		const typeB = this.b.getType( builder );
 
 
-		// use the greater length vector
+		if ( builder.isMatrix( typeA ) && builder.isVector( typeB ) ) {
 
 
-		if ( builder.getTypeLength( typeB ) > builder.getTypeLength( typeA ) ) {
+			// matrix x vector
+
+			return typeB;
+
+		} else if ( builder.isVector( typeA ) && builder.isMatrix( typeB ) ) {
+
+			// vector x matrix
+
+			return typeA;
+
+		} else if ( builder.getTypeLength( typeB ) > builder.getTypeLength( typeA ) ) {
+
+			// anytype x anytype: use the greater length vector
 
 
 			return typeB;
 			return typeB;
 
 
@@ -29,13 +41,42 @@ class OperatorNode extends Node {
 		return typeA;
 		return typeA;
 
 
 	}
 	}
+	
+	getVectorFromMatrix( type ) {
+		
+		return 'vec' + type.substr( 3 );
+		
+	}
 
 
 	generate( builder, output ) {
 	generate( builder, output ) {
 
 
-		const type = this.getType( builder );
-
-		const a = this.a.build( builder, type );
-		const b = this.b.build( builder, type );
+		let typeA = this.a.getType( builder );
+		let typeB = this.b.getType( builder );
+
+		let type = this.getType( builder );
+
+		if ( builder.isMatrix( typeA ) && builder.isVector( typeB ) ) {
+			
+			// matrix x vector
+			
+			type = typeB = this.getVectorFromMatrix( typeA );
+
+		} else if ( builder.isVector( typeA ) && builder.isMatrix( typeB ) ) {
+			
+			// vector x matrix
+			
+			type = typeB = this.getVectorFromMatrix( typeB );
+
+		} else {
+			
+			// anytype x anytype
+			
+			typeA = typeB = type;
+			
+		}
+		
+		const a = this.a.build( builder, typeA );
+		const b = this.b.build( builder, typeB );
 
 
 		return builder.format( `( ${a} ${this.op} ${b} )`, type, output );
 		return builder.format( `( ${a} ${this.op} ${b} )`, type, output );
 
 

+ 2 - 1
examples/jsm/renderers/nodes/utils/TimerNode.js

@@ -1,4 +1,5 @@
 import FloatNode from '../inputs/FloatNode.js';
 import FloatNode from '../inputs/FloatNode.js';
+import { NodeUpdateType } from '../core/constants.js';
 
 
 class TimerNode extends FloatNode {
 class TimerNode extends FloatNode {
 
 
@@ -6,7 +7,7 @@ class TimerNode extends FloatNode {
 
 
 		super();
 		super();
 
 
-		this.needsUpdate = true;
+		this.updateType = NodeUpdateType.Frame;
 
 
 	}
 	}
 
 

+ 2 - 0
examples/jsm/renderers/webgpu/WebGPUBinding.js

@@ -7,6 +7,8 @@ class WebGPUBinding {
 
 
 		this.type = null; // read-only
 		this.type = null; // read-only
 
 
+		this.isShared = false;
+
 	}
 	}
 
 
 	setVisibility( visibility ) {
 	setVisibility( visibility ) {

+ 7 - 70
examples/jsm/renderers/webgpu/WebGPUBindings.js

@@ -16,12 +16,8 @@ class WebGPUBindings {
 
 
 		this.uniformsData = new WeakMap();
 		this.uniformsData = new WeakMap();
 
 
-		this.sharedUniformsGroups = new Map();
-
 		this.updateMap = new WeakMap();
 		this.updateMap = new WeakMap();
 
 
-		this._setupSharedUniformsGroups();
-
 	}
 	}
 
 
 	get( object ) {
 	get( object ) {
@@ -37,7 +33,7 @@ class WebGPUBindings {
 
 
 			// each material defines an array of bindings (ubos, textures, samplers etc.)
 			// each material defines an array of bindings (ubos, textures, samplers etc.)
 
 
-			const bindings = this.composeBindings( object, nodeBuilder.getBindings( 'fragment' ) );
+			const bindings = nodeBuilder.getBindings();
 
 
 			// setup (static) binding layout and (dynamic) binding group
 			// setup (static) binding layout and (dynamic) binding group
 
 
@@ -92,7 +88,6 @@ class WebGPUBindings {
 
 
 		const updateMap = this.updateMap;
 		const updateMap = this.updateMap;
 		const frame = this.info.render.frame;
 		const frame = this.info.render.frame;
-		const sharedUniformsGroups = this.sharedUniformsGroups;
 
 
 		let needsBindGroupRefresh = false;
 		let needsBindGroupRefresh = false;
 
 
@@ -100,12 +95,12 @@ class WebGPUBindings {
 
 
 		for ( const binding of bindings ) {
 		for ( const binding of bindings ) {
 
 
-			if ( binding.isUniformsGroup ) {
+			const isShared = binding.isShared;;
+			const isUpdated = updateMap.get( binding ) === frame;
 
 
-				const isShared = sharedUniformsGroups.has( binding.name );
-				const isUpdated = updateMap.get( binding ) === frame;
+			if ( isShared && isUpdated ) continue;
 
 
-				if ( isShared && isUpdated ) continue;
+			if ( binding.isUniformsGroup ) {
 
 
 				const array = binding.array;
 				const array = binding.array;
 				const bufferGPU = binding.bufferGPU;
 				const bufferGPU = binding.bufferGPU;
@@ -125,8 +120,6 @@ class WebGPUBindings {
 
 
 				}
 				}
 
 
-				updateMap.set( binding, frame );
-
 			} else if ( binding.isStorageBuffer ) {
 			} else if ( binding.isStorageBuffer ) {
 
 
 				const attribute = binding.attribute;
 				const attribute = binding.attribute;
@@ -163,6 +156,8 @@ class WebGPUBindings {
 
 
 			}
 			}
 
 
+			updateMap.set( binding, frame );
+
 		}
 		}
 
 
 		if ( needsBindGroupRefresh === true ) {
 		if ( needsBindGroupRefresh === true ) {
@@ -258,64 +253,6 @@ class WebGPUBindings {
 
 
 	}
 	}
 
 
-	composeBindings( object, uniforms ) {
-
-		const bindings = [];
-
-		// UBOs
-
-		// model
-
-		const modelViewUniform = new Matrix4Uniform( 'modelMatrix' );
-		const modelViewMatrixUniform = new Matrix4Uniform( 'modelViewMatrix' );
-		const normalMatrixUniform = new Matrix3Uniform( 'normalMatrix' );
-
-		const modelGroup = new WebGPUUniformsGroup( 'modelUniforms' );
-		modelGroup.addUniform( modelViewUniform );
-		modelGroup.addUniform( modelViewMatrixUniform );
-		modelGroup.addUniform( normalMatrixUniform );
-		modelGroup.setOnBeforeUpdate( function ( object/*, camera */ ) {
-
-			modelViewUniform.setValue( object.matrixWorld );
-			modelViewMatrixUniform.setValue( object.modelViewMatrix );
-			normalMatrixUniform.setValue( object.normalMatrix );
-
-		} );
-
-		// camera
-
-		const cameraGroup = this.sharedUniformsGroups.get( 'cameraUniforms' );
-
-		// the order of WebGPUBinding objects must match the binding order in the shader
-
-		bindings.push( modelGroup );
-		bindings.push( cameraGroup );
-
-		bindings.push( ... uniforms );
-
-		return bindings;
-
-	}
-
-	_setupSharedUniformsGroups() {
-
-		const projectionMatrixUniform = new Matrix4Uniform( 'projectionMatrix' );
-		const viewMatrixUniform = new Matrix4Uniform( 'viewMatrix' );
-
-		const cameraGroup = new WebGPUUniformsGroup( 'cameraUniforms' );
-		cameraGroup.addUniform( projectionMatrixUniform );
-		cameraGroup.addUniform( viewMatrixUniform );
-		cameraGroup.setOnBeforeUpdate( function ( object, camera ) {
-
-			projectionMatrixUniform.setValue( camera.projectionMatrix );
-			viewMatrixUniform.setValue( camera.matrixWorldInverse );
-
-		} );
-
-		this.sharedUniformsGroups.set( cameraGroup.name, cameraGroup );
-
-	}
-
 }
 }
 
 
 export default WebGPUBindings;
 export default WebGPUBindings;

+ 21 - 126
examples/jsm/renderers/webgpu/nodes/ShaderLib.js

@@ -1,145 +1,40 @@
 const ShaderLib = {
 const ShaderLib = {
-	meshBasic: {
+	common: {
 		vertexShader: `#version 450
 		vertexShader: `#version 450
 
 
-		layout(location = 0) in vec3 position;
+NODE_HEADER_ATTRIBUTES
+NODE_HEADER_UNIFORMS
+NODE_HEADER_VARYS
 
 
-		NODE_HEADER_ATTRIBUTES
-		NODE_HEADER_UNIFORMS
-
-		layout(set = 0, binding = 0) uniform ModelUniforms {
-			mat4 modelMatrix;
-			mat4 modelViewMatrix;
-			mat3 normalMatrix;
-		} modelUniforms;
-
-		layout(set = 0, binding = 1) uniform CameraUniforms {
-			mat4 projectionMatrix;
-			mat4 viewMatrix;
-		} cameraUniforms;
-
-		void main(){
-			NODE_BODY_ATTRIBUTES
-			gl_Position = cameraUniforms.projectionMatrix * modelUniforms.modelViewMatrix * vec4( position, 1.0 );
-		}`,
-		fragmentShader: `#version 450
-
-		NODE_HEADER_ATTRIBUTES
-		NODE_HEADER_UNIFORMS
-
-		layout(location = 0) out vec4 outColor;
-
-		void main() {
-
-			outColor = vec4( 1.0, 1.0, 1.0, 1.0 );
-
-			#ifdef NODE_COLOR
-
-				outColor = NODE_COLOR;
-
-			#endif
-
-			#ifdef NODE_OPACITY
-
-				outColor.a *= NODE_OPACITY;
-
-			#endif
-
-		}`
-	},
-	pointsBasic: {
-		vertexShader: `#version 450
-
-		layout(location = 0) in vec3 position;
-
-		NODE_HEADER_ATTRIBUTES
-		NODE_HEADER_UNIFORMS
-
-		layout(set = 0, binding = 0) uniform ModelUniforms {
-			mat4 modelMatrix;
-			mat4 modelViewMatrix;
-		} modelUniforms;
-
-		layout(set = 0, binding = 1) uniform CameraUniforms {
-			mat4 projectionMatrix;
-			mat4 viewMatrix;
-		} cameraUniforms;
-
-		void main(){
-			NODE_BODY_ATTRIBUTES
-			gl_Position = cameraUniforms.projectionMatrix * modelUniforms.modelViewMatrix * vec4( position, 1.0 );
-		}`,
-		fragmentShader: `#version 450
-
-		NODE_HEADER_ATTRIBUTES
-		NODE_HEADER_UNIFORMS
-
-		layout(location = 0) out vec4 outColor;
-
-		void main() {
-
-			outColor = vec4( 1.0, 1.0, 1.0, 1.0 );
-
-			#ifdef NODE_COLOR
-
-				outColor = NODE_COLOR;
-
-			#endif
-
-			#ifdef NODE_OPACITY
-
-				outColor.a = NODE_OPACITY;
-
-			#endif
-
-		}`
-	},
-	lineBasic: {
-		vertexShader: `#version 450
-
-		layout(location = 0) in vec3 position;
-
-		NODE_HEADER_ATTRIBUTES
-		NODE_HEADER_UNIFORMS
-
-		layout(set = 0, binding = 0) uniform ModelUniforms {
-			mat4 modelMatrix;
-			mat4 modelViewMatrix;
-		} modelUniforms;
-
-		layout(set = 0, binding = 1) uniform CameraUniforms {
-			mat4 projectionMatrix;
-			mat4 viewMatrix;
-		} cameraUniforms;
-
-		void main(){
-			NODE_BODY_ATTRIBUTES
-			gl_Position = cameraUniforms.projectionMatrix * modelUniforms.modelViewMatrix * vec4( position, 1.0 );
-		}`,
+void main(){
+	NODE_BODY_VARYS
+	gl_Position = NODE_GL_POSITION;
+}`,
 		fragmentShader: `#version 450
 		fragmentShader: `#version 450
 
 
-		NODE_HEADER_ATTRIBUTES
-		NODE_HEADER_UNIFORMS
+NODE_HEADER_ATTRIBUTES
+NODE_HEADER_UNIFORMS
+NODE_HEADER_VARYS
 
 
-		layout(location = 0) out vec4 outColor;
+layout(location = 0) out vec4 outColor;
 
 
-		void main() {
+void main() {
 
 
-			outColor = vec4( 1.0, 1.0, 1.0, 1.0 );
+	outColor = vec4( 1.0, 1.0, 1.0, 1.0 );
 
 
-			#ifdef NODE_COLOR
+	#ifdef NODE_COLOR
 
 
-				outColor = NODE_COLOR;
+		outColor = NODE_COLOR;
 
 
-			#endif
+	#endif
 
 
-			#ifdef NODE_OPACITY
+	#ifdef NODE_OPACITY
 
 
-				outColor.a = NODE_OPACITY;
+		outColor.a *= NODE_OPACITY;
 
 
-			#endif
+	#endif
 
 
-		}`
+}`
 	}
 	}
 };
 };
 
 

+ 81 - 53
examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js

@@ -1,10 +1,14 @@
 import WebGPUNodeUniformsGroup from './WebGPUNodeUniformsGroup.js';
 import WebGPUNodeUniformsGroup from './WebGPUNodeUniformsGroup.js';
-import { FloatNodeUniform, Vector2NodeUniform, Vector3NodeUniform, Vector4NodeUniform, ColorNodeUniform } from './WebGPUNodeUniform.js';
+import { 
+	FloatNodeUniform, Vector2NodeUniform, Vector3NodeUniform, Vector4NodeUniform, 
+	ColorNodeUniform, Matrix3NodeUniform, Matrix4NodeUniform
+} from './WebGPUNodeUniform.js';
 import WebGPUSampler from '../WebGPUSampler.js';
 import WebGPUSampler from '../WebGPUSampler.js';
 import { WebGPUSampledTexture } from '../WebGPUSampledTexture.js';
 import { WebGPUSampledTexture } from '../WebGPUSampledTexture.js';
 
 
 import NodeSlot from '../../nodes/core/NodeSlot.js';
 import NodeSlot from '../../nodes/core/NodeSlot.js';
 import NodeBuilder from '../../nodes/core/NodeBuilder.js';
 import NodeBuilder from '../../nodes/core/NodeBuilder.js';
+import WVPNode from '../../nodes/accessors/WVPNode.js';
 
 
 import ShaderLib from './ShaderLib.js';
 import ShaderLib from './ShaderLib.js';
 
 
@@ -14,11 +18,8 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 		super( material, renderer );
 		super( material, renderer );
 
 
-		this.bindingIndex = 2;
 		this.bindings = { vertex: [], fragment: [] };
 		this.bindings = { vertex: [], fragment: [] };
-
-		this.attributeIndex = 1;
-		this.varyIndex = 0;
+		this.bindingsOffset = { vertex: 0, fragment: 0 };
 
 
 		this.uniformsGroup = {};
 		this.uniformsGroup = {};
 
 
@@ -34,27 +35,21 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 		// get shader
 		// get shader
 
 
-		if ( material.isMeshBasicMaterial ) {
-
-			this.nativeShader = ShaderLib.meshBasic;
-
-		} else if ( material.isPointsMaterial ) {
+		this.nativeShader = ShaderLib.common;
 
 
-			this.nativeShader = ShaderLib.pointsBasic;
-
-		} else if ( material.isLineBasicMaterial ) {
+		// parse inputs
 
 
-			this.nativeShader = ShaderLib.lineBasic;
+		if ( material.isMeshBasicMaterial || material.isPointsMaterial || material.isLineBasicMaterial ) {
 
 
-		} else {
+			const wvpNode = new WVPNode();
 
 
-			console.error( 'THREE.WebGPURenderer: Unknwon shader type.' );
+			if ( material.positionNode !== undefined ) {
 
 
-		}
+				wvpNode.position = material.positionNode;
 
 
-		// parse inputs
+			}
 
 
-		if ( material.isMeshBasicMaterial || material.isPointsMaterial || material.isLineBasicMaterial ) {
+			this.addSlot( 'vertex', new NodeSlot( wvpNode, 'GL_POSITION', 'vec4' ) );
 
 
 			if ( material.colorNode !== undefined ) {
 			if ( material.colorNode !== undefined ) {
 
 
@@ -78,23 +73,34 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 	}
 	}
 
 
-	getPropertyName( nodeUniform ) {
+	getPropertyName( node ) {
+
+		if (node.isNodeUniform) {
 
 
-		if ( nodeUniform.type === 'texture' ) {
+			const name = node.name;
+			const type = node.type;
 
 
-			return nodeUniform.name;
+			if ( type === 'texture' ) {
 
 
-		} else {
+				return name;
+
+			} else {
 
 
-			return `nodeUniforms.${nodeUniform.name}`;
+				return `nodeUniforms.${name}`;
 
 
+			}
+			
 		}
 		}
+		
+		return super.getPropertyName( node );
 
 
 	}
 	}
 
 
-	getBindings( shaderStage ) {
+	getBindings() {
+
+		const bindings = this.bindings;
 
 
-		return this.bindings[ shaderStage ];
+		return [ ...bindings.vertex, ...bindings.fragment ];
 
 
 	}
 	}
 
 
@@ -156,6 +162,14 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 					uniformGPU = new ColorNodeUniform( uniformNode );
 					uniformGPU = new ColorNodeUniform( uniformNode );
 
 
+				} else if ( type === 'mat3' ) {
+
+					uniformGPU = new Matrix3NodeUniform( uniformNode );
+
+				} else if ( type === 'mat4' ) {
+
+					uniformGPU = new Matrix4NodeUniform( uniformNode );
+
 				} else {
 				} else {
 
 
 					throw new Error( `Uniform "${type}" not declared.` );
 					throw new Error( `Uniform "${type}" not declared.` );
@@ -168,6 +182,12 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 			nodeData.uniformGPU = uniformGPU;
 			nodeData.uniformGPU = uniformGPU;
 
 
+			if ( shaderStage === 'vertex' ) {
+				
+				this.bindingsOffset[ 'fragment' ] = bindings.length;
+				
+			}
+
 		}
 		}
 
 
 		return uniformNode;
 		return uniformNode;
@@ -178,49 +198,56 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 		let snippet = '';
 		let snippet = '';
 
 
-		const attributes = this.attributes;
+		if ( shaderStage === 'vertex' ) {
 
 
-		let attributeIndex = this.attributeIndex;
-		let varyIndex = this.varyIndex;
+			const attributes = this.attributes;
 
 
-		for ( const name in attributes ) {
-
-			const attribute = attributes[ name ];
+			for ( let index = 0; index < attributes.length; index++ ) {
+				
+				const attribute = attributes[ index ];
+				
+				snippet += `layout(location = ${index}) in ${attribute.type} ${attribute.name};`;
+			
+			}
+			
+		}
 
 
-			const type = attribute.type;
-			const property = attribute.property;
+		return snippet;
 
 
-			if ( shaderStage === 'vertex' ) {
+	}
 
 
-				snippet += `layout(location = ${attributeIndex ++}) in ${type} ${name};`;
-				snippet += `layout(location = ${varyIndex ++}) out ${type} ${property};`;
+	getVarysHeaderSnippet( shaderStage ) {
 
 
-			} else if ( shaderStage === 'fragment' ) {
+		let snippet = '';
 
 
-				snippet += `layout(location = ${varyIndex ++}) in ${type} ${property};`;
+		const varys = this.varys;
 
 
-			}
+		const ioStage = shaderStage === 'vertex' ? 'out' : 'in';
 
 
+		for ( let index = 0; index < varys.length; index++ ) {
+				
+			const vary = varys[ index ];
+			
+			snippet += `layout(location = ${index}) ${ioStage} ${vary.type} ${vary.name};`;
+		
 		}
 		}
 
 
 		return snippet;
 		return snippet;
 
 
 	}
 	}
 
 
-	getAttributesBodySnippet( /* shaderStage */ ) {
+	getVarysBodySnippet( shaderStage ) {
 
 
 		let snippet = '';
 		let snippet = '';
 
 
-		const attributes = this.attributes;
+		if ( shaderStage === 'vertex' ) {
 
 
-		for ( const name in attributes ) {
+			for ( const vary of this.varys ) {
 
 
-			const attribute = attributes[ name ];
-
-			const property = attribute.property;
-
-			snippet += `${property} = ${name};`;
+				snippet += `${vary.name} = ${vary.value};`;
 
 
+			}
+			
 		}
 		}
 
 
 		return snippet;
 		return snippet;
@@ -234,14 +261,14 @@ class WebGPUNodeBuilder extends NodeBuilder {
 		let snippet = '';
 		let snippet = '';
 		let groupSnippet = '';
 		let groupSnippet = '';
 
 
-		let bindingIndex = this.bindingIndex;
+		let index = this.bindingsOffset[ shaderStage ];
 
 
 		for ( const uniform of uniforms ) {
 		for ( const uniform of uniforms ) {
 
 
 			if ( uniform.type === 'texture' ) {
 			if ( uniform.type === 'texture' ) {
 
 
-				snippet += `layout(set = 0, binding = ${bindingIndex ++}) uniform sampler ${uniform.name}_sampler;`;
-				snippet += `layout(set = 0, binding = ${bindingIndex ++}) uniform texture2D ${uniform.name};`;
+				snippet += `layout(set = 0, binding = ${index ++}) uniform sampler ${uniform.name}_sampler;`;
+				snippet += `layout(set = 0, binding = ${index ++}) uniform texture2D ${uniform.name};`;
 
 
 			} else {
 			} else {
 
 
@@ -255,7 +282,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 		if ( groupSnippet ) {
 		if ( groupSnippet ) {
 
 
-			snippet += `layout(set = 0, binding = ${bindingIndex ++}) uniform NodeUniforms { ${groupSnippet} } nodeUniforms;`;
+			snippet += `layout(set = 0, binding = ${index ++}) uniform NodeUniforms { ${groupSnippet} } nodeUniforms;`;
 
 
 		}
 		}
 
 
@@ -284,7 +311,8 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 
 		this.vertexShader = this.composeShaderCode( this.nativeShader.vertexShader, this.vertexShader );
 		this.vertexShader = this.composeShaderCode( this.nativeShader.vertexShader, this.vertexShader );
 		this.fragmentShader = this.composeShaderCode( this.nativeShader.fragmentShader, this.fragmentShader );
 		this.fragmentShader = this.composeShaderCode( this.nativeShader.fragmentShader, this.fragmentShader );
-
+console.log( this.vertexShader );
+console.log( this.fragmentShader );
 		return this;
 		return this;
 
 
 	}
 	}

+ 0 - 9
examples/jsm/renderers/webgpu/nodes/WebGPUNodeUniformsGroup.js

@@ -13,16 +13,7 @@ class WebGPUNodeUniformsGroup extends WebGPUUniformsGroup {
 
 
 		this.setVisibility( shaderStageVisibility );
 		this.setVisibility( shaderStageVisibility );
 
 
-		//this.setOnBeforeUpdate( this._onBeforeUpdate );
-
-	}
-	/*
-	_onBeforeUpdate( object, camera ) {
-
-		const material = object.material;
-
 	}
 	}
-	*/
 
 
 }
 }
 
 

+ 8 - 5
examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js

@@ -29,9 +29,9 @@ class WebGPUNodes {
 
 
 	}
 	}
 
 
-	remove( object ) {
+	remove( material ) {
 
 
-		this.builders.delete( object );
+		this.builders.delete( material );
 
 
 	}
 	}
 
 
@@ -41,17 +41,20 @@ class WebGPUNodes {
 
 
 	}
 	}
 
 
-	update( object/*, camera*/ ) {
+	update( object, camera ) {
 
 
 		const material = object.material;
 		const material = object.material;
 
 
 		const nodeBuilder = this.get( material );
 		const nodeBuilder = this.get( material );
+		const nodeFrame = this.nodeFrame;
 
 
-		this.nodeFrame.material = object.material;
+		nodeFrame.material = material;
+		nodeFrame.camera = camera;
+		nodeFrame.object = object;
 
 
 		for ( const node of nodeBuilder.updateNodes ) {
 		for ( const node of nodeBuilder.updateNodes ) {
 
 
-			this.nodeFrame.updateNode( node );
+			nodeFrame.updateNode( node );
 
 
 		}
 		}
 
 

+ 20 - 6
examples/webgpu_sandbox.html

@@ -22,9 +22,14 @@
 			import AttributeNode from './jsm/renderers/nodes/core/AttributeNode.js';
 			import AttributeNode from './jsm/renderers/nodes/core/AttributeNode.js';
 			import FloatNode from './jsm/renderers/nodes/inputs/FloatNode.js';
 			import FloatNode from './jsm/renderers/nodes/inputs/FloatNode.js';
 			import Vector2Node from './jsm/renderers/nodes/inputs/Vector2Node.js';
 			import Vector2Node from './jsm/renderers/nodes/inputs/Vector2Node.js';
+			import Vector3Node from './jsm/renderers/nodes/inputs/Vector3Node.js';
+			import Vector4Node from './jsm/renderers/nodes/inputs/Vector4Node.js';
+			import Matrix4Node from './jsm/renderers/nodes/inputs/Matrix4Node.js';
 			import ColorNode from './jsm/renderers/nodes/inputs/ColorNode.js';
 			import ColorNode from './jsm/renderers/nodes/inputs/ColorNode.js';
 			import TextureNode from './jsm/renderers/nodes/inputs/TextureNode.js';
 			import TextureNode from './jsm/renderers/nodes/inputs/TextureNode.js';
 			import UVNode from './jsm/renderers/nodes/accessors/UVNode.js';
 			import UVNode from './jsm/renderers/nodes/accessors/UVNode.js';
+			import PositionNode from './jsm/renderers/nodes/accessors/PositionNode.js';
+			import WVPNode from './jsm/renderers/nodes/accessors/WVPNode.js';
 			import OperatorNode from './jsm/renderers/nodes/math/OperatorNode.js';
 			import OperatorNode from './jsm/renderers/nodes/math/OperatorNode.js';
 			import SwitchNode from './jsm/renderers/nodes/utils/SwitchNode.js';
 			import SwitchNode from './jsm/renderers/nodes/utils/SwitchNode.js';
 			import TimerNode from './jsm/renderers/nodes/utils/TimerNode.js';
 			import TimerNode from './jsm/renderers/nodes/utils/TimerNode.js';
@@ -59,6 +64,11 @@
 				texture.wrapT = THREE.RepeatWrapping;
 				texture.wrapT = THREE.RepeatWrapping;
 				texture.name = 'uv_grid';
 				texture.name = 'uv_grid';
 
 
+				const textureDisplaceLoader = new THREE.TextureLoader();
+				const textureDisplace = textureLoader.load( './textures/transition/transition1.png' );
+				textureDisplace.wrapS = THREE.RepeatWrapping;
+				textureDisplace.wrapT = THREE.RepeatWrapping;
+
 				// compressed texture
 				// compressed texture
 
 
 				const ddsLoader = new DDSLoader();
 				const ddsLoader = new DDSLoader();
@@ -67,6 +77,7 @@
 				//
 				//
 
 
 				const geometryBox = new THREE.BoxGeometry();
 				const geometryBox = new THREE.BoxGeometry();
+				const geometrySphere = new THREE.SphereGeometry( .5, 64, 64 );
 				const materialBox = new THREE.MeshBasicMaterial( { map: texture } );
 				const materialBox = new THREE.MeshBasicMaterial( { map: texture } );
 
 
 				const timerNode = new TimerNode();
 				const timerNode = new TimerNode();
@@ -75,13 +86,18 @@
 				const timerScaleNode = new OperatorNode( '*', timerNode, new Vector2Node( new THREE.Vector2( - 0.5, 0.1 ) ).setConst( true ) );
 				const timerScaleNode = new OperatorNode( '*', timerNode, new Vector2Node( new THREE.Vector2( - 0.5, 0.1 ) ).setConst( true ) );
 				const animateUV = new OperatorNode( '+', new UVNode(), timerScaleNode );
 				const animateUV = new OperatorNode( '+', new UVNode(), timerScaleNode );
 
 
-				materialBox.colorNode = new TextureNode( texture, animateUV );
+				//materialBox.colorNode = new TextureNode( texture, animateUV );
+
+				const displaceScaled = new OperatorNode( '*', new TextureNode( textureDisplace, animateUV ), new FloatNode( .1 ) );
+
+				materialBox.positionNode = new OperatorNode( '+', new PositionNode(), displaceScaled );
+				materialBox.colorNode = new TextureNode( textureDisplace, animateUV );
 
 
 				// test uv 2
 				// test uv 2
 				//geometryBox.setAttribute( 'uv2', geometryBox.getAttribute( 'uv' ) );
 				//geometryBox.setAttribute( 'uv2', geometryBox.getAttribute( 'uv' ) );
 				//materialBox.colorNode = new TextureNode( texture, new UVNode( 1 ) );
 				//materialBox.colorNode = new TextureNode( texture, new UVNode( 1 ) );
 
 
-				box = new THREE.Mesh( geometryBox, materialBox );
+				box = new THREE.Mesh( geometrySphere, materialBox );
 				box.position.set( 0, 1, 0 );
 				box.position.set( 0, 1, 0 );
 				scene.add( box );
 				scene.add( box );
 
 
@@ -121,9 +137,7 @@
 				const geometryPoints = new THREE.BufferGeometry().setFromPoints( points );
 				const geometryPoints = new THREE.BufferGeometry().setFromPoints( points );
 				const materialPoints = new THREE.PointsMaterial();
 				const materialPoints = new THREE.PointsMaterial();
 
 
-				geometryPoints.setAttribute( 'color', geometryPoints.getAttribute( 'position' ) );
-
-				materialPoints.colorNode = new OperatorNode( '*', new AttributeNode( 'vec3', 'color' ), new FloatNode( 3 ).setConst( true ) );
+				materialPoints.colorNode = new OperatorNode( '*', new PositionNode(), new FloatNode( 3 ).setConst( true ) );
 
 
 				const pointCloud = new THREE.Points( geometryPoints, materialPoints );
 				const pointCloud = new THREE.Points( geometryPoints, materialPoints );
 				pointCloud.position.set( 2, - 1, 0 );
 				pointCloud.position.set( 2, - 1, 0 );
@@ -141,7 +155,7 @@
 				geometryLine.setAttribute( 'color', geometryLine.getAttribute( 'position' ) );
 				geometryLine.setAttribute( 'color', geometryLine.getAttribute( 'position' ) );
 
 
 				const materialLine = new THREE.LineBasicMaterial();
 				const materialLine = new THREE.LineBasicMaterial();
-				materialLine.colorNode = new AttributeNode( 'vec3', 'color' );
+				materialLine.colorNode = new AttributeNode( 'color', 'vec3' );
 
 
 				const line = new THREE.Line( geometryLine, materialLine );
 				const line = new THREE.Line( geometryLine, materialLine );
 				line.position.set( 2, 1, 0 );
 				line.position.set( 2, 1, 0 );