|
@@ -1,10 +1,14 @@
|
|
|
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 { WebGPUSampledTexture } from '../WebGPUSampledTexture.js';
|
|
|
|
|
|
import NodeSlot from '../../nodes/core/NodeSlot.js';
|
|
|
import NodeBuilder from '../../nodes/core/NodeBuilder.js';
|
|
|
+import WVPNode from '../../nodes/accessors/WVPNode.js';
|
|
|
|
|
|
import ShaderLib from './ShaderLib.js';
|
|
|
|
|
@@ -14,11 +18,8 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
super( material, renderer );
|
|
|
|
|
|
- this.bindingIndex = 2;
|
|
|
this.bindings = { vertex: [], fragment: [] };
|
|
|
-
|
|
|
- this.attributeIndex = 1;
|
|
|
- this.varyIndex = 0;
|
|
|
+ this.bindingsOffset = { vertex: 0, fragment: 0 };
|
|
|
|
|
|
this.uniformsGroup = {};
|
|
|
|
|
@@ -34,27 +35,21 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
// 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 ) {
|
|
|
|
|
@@ -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 );
|
|
|
|
|
|
+ } else if ( type === 'mat3' ) {
|
|
|
+
|
|
|
+ uniformGPU = new Matrix3NodeUniform( uniformNode );
|
|
|
+
|
|
|
+ } else if ( type === 'mat4' ) {
|
|
|
+
|
|
|
+ uniformGPU = new Matrix4NodeUniform( uniformNode );
|
|
|
+
|
|
|
} else {
|
|
|
|
|
|
throw new Error( `Uniform "${type}" not declared.` );
|
|
@@ -168,6 +182,12 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
nodeData.uniformGPU = uniformGPU;
|
|
|
|
|
|
+ if ( shaderStage === 'vertex' ) {
|
|
|
+
|
|
|
+ this.bindingsOffset[ 'fragment' ] = bindings.length;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
return uniformNode;
|
|
@@ -178,49 +198,56 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
- getAttributesBodySnippet( /* shaderStage */ ) {
|
|
|
+ getVarysBodySnippet( shaderStage ) {
|
|
|
|
|
|
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;
|
|
@@ -234,14 +261,14 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
let snippet = '';
|
|
|
let groupSnippet = '';
|
|
|
|
|
|
- let bindingIndex = this.bindingIndex;
|
|
|
+ let index = this.bindingsOffset[ shaderStage ];
|
|
|
|
|
|
for ( const uniform of uniforms ) {
|
|
|
|
|
|
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 {
|
|
|
|
|
@@ -255,7 +282,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
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.fragmentShader = this.composeShaderCode( this.nativeShader.fragmentShader, this.fragmentShader );
|
|
|
-
|
|
|
+console.log( this.vertexShader );
|
|
|
+console.log( this.fragmentShader );
|
|
|
return this;
|
|
|
|
|
|
}
|