|
@@ -758,7 +758,13 @@ class WGSLNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
|
|
} else if ( type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer' ) {
|
|
} else if ( type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer' ) {
|
|
|
|
|
|
|
|
- return `NodeBuffer_${ node.id }.${name}`;
|
|
|
|
|
|
|
+ if ( this.isCustomStruct( node ) ) {
|
|
|
|
|
+
|
|
|
|
|
+ return name;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return name + '.value';
|
|
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
|
@@ -899,7 +905,7 @@ class WGSLNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
|
|
if ( ( shaderStage === 'fragment' || shaderStage === 'compute' ) && this.isUnfilterable( node.value ) === false && texture.store === false ) {
|
|
if ( ( shaderStage === 'fragment' || shaderStage === 'compute' ) && this.isUnfilterable( node.value ) === false && texture.store === false ) {
|
|
|
|
|
|
|
|
- const sampler = new NodeSampler( `${uniformNode.name}_sampler`, uniformNode.node, group );
|
|
|
|
|
|
|
+ const sampler = new NodeSampler( `${ uniformNode.name }_sampler`, uniformNode.node, group );
|
|
|
sampler.setVisibility( gpuShaderStageLib[ shaderStage ] );
|
|
sampler.setVisibility( gpuShaderStageLib[ shaderStage ] );
|
|
|
|
|
|
|
|
bindings.push( sampler, texture );
|
|
bindings.push( sampler, texture );
|
|
@@ -925,6 +931,8 @@ class WGSLNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
|
|
uniformGPU = buffer;
|
|
uniformGPU = buffer;
|
|
|
|
|
|
|
|
|
|
+ uniformNode.name = name ? name : 'NodeBuffer_' + uniformNode.id;
|
|
|
|
|
+
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
|
|
const uniformsStage = this.uniformGroups[ shaderStage ] || ( this.uniformGroups[ shaderStage ] = {} );
|
|
const uniformsStage = this.uniformGroups[ shaderStage ] || ( this.uniformGroups[ shaderStage ] = {} );
|
|
@@ -1424,18 +1432,22 @@ ${ flowData.code }
|
|
|
getStructMembers( struct ) {
|
|
getStructMembers( struct ) {
|
|
|
|
|
|
|
|
const snippets = [];
|
|
const snippets = [];
|
|
|
- const members = struct.getMemberTypes();
|
|
|
|
|
|
|
|
|
|
- for ( let i = 0; i < members.length; i ++ ) {
|
|
|
|
|
|
|
+ for ( const member of struct.members ) {
|
|
|
|
|
|
|
|
- const member = members[ i ];
|
|
|
|
|
- snippets.push( `\t@location( ${i} ) m${i} : ${ member }<f32>` );
|
|
|
|
|
|
|
+ const prefix = struct.output ? '@location( ' + member.index + ' ) ' : '';
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ let type = this.getType( member.type );
|
|
|
|
|
|
|
|
- const builtins = this.getBuiltins( 'output' );
|
|
|
|
|
|
|
+ if ( member.atomic ) {
|
|
|
|
|
|
|
|
- if ( builtins ) snippets.push( '\t' + builtins );
|
|
|
|
|
|
|
+ type = 'atomic< ' + type + ' >';
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ snippets.push( `\t${ prefix + member.name } : ${ type }` );
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
return snippets.join( ',\n' );
|
|
return snippets.join( ',\n' );
|
|
|
|
|
|
|
@@ -1449,26 +1461,29 @@ ${ flowData.code }
|
|
|
*/
|
|
*/
|
|
|
getStructs( shaderStage ) {
|
|
getStructs( shaderStage ) {
|
|
|
|
|
|
|
|
- const snippets = [];
|
|
|
|
|
|
|
+ let result = '';
|
|
|
|
|
+
|
|
|
const structs = this.structs[ shaderStage ];
|
|
const structs = this.structs[ shaderStage ];
|
|
|
|
|
|
|
|
- for ( let index = 0, length = structs.length; index < length; index ++ ) {
|
|
|
|
|
|
|
+ if ( structs.length > 0 ) {
|
|
|
|
|
+
|
|
|
|
|
+ const snippets = [];
|
|
|
|
|
|
|
|
- const struct = structs[ index ];
|
|
|
|
|
- const name = struct.name;
|
|
|
|
|
|
|
+ for ( const struct of structs ) {
|
|
|
|
|
|
|
|
- let snippet = `\struct ${ name } {\n`;
|
|
|
|
|
- snippet += this.getStructMembers( struct );
|
|
|
|
|
- snippet += '\n}';
|
|
|
|
|
|
|
+ let snippet = `struct ${ struct.name } {\n`;
|
|
|
|
|
+ snippet += this.getStructMembers( struct );
|
|
|
|
|
+ snippet += '\n};';
|
|
|
|
|
|
|
|
|
|
+ snippets.push( snippet );
|
|
|
|
|
|
|
|
- snippets.push( snippet );
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- snippets.push( `\nvar<private> output : ${ name };\n\n` );
|
|
|
|
|
|
|
+ result = '\n' + snippets.join( '\n\n' ) + '\n';
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return snippets.join( '\n\n' );
|
|
|
|
|
|
|
+ return result;
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1581,6 +1596,12 @@ ${ flowData.code }
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ isCustomStruct( nodeUniform ) {
|
|
|
|
|
+
|
|
|
|
|
+ return nodeUniform.value.isStorageBufferAttribute && nodeUniform.node.structTypeNode !== null;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Returns the uniforms of the given shader stage as a WGSL string.
|
|
* Returns the uniforms of the given shader stage as a WGSL string.
|
|
|
*
|
|
*
|
|
@@ -1662,7 +1683,7 @@ ${ flowData.code }
|
|
|
|
|
|
|
|
const componentPrefix = this.getComponentTypeFromTexture( texture ).charAt( 0 );
|
|
const componentPrefix = this.getComponentTypeFromTexture( texture ).charAt( 0 );
|
|
|
|
|
|
|
|
- textureType = `texture${multisampled}_2d<${ componentPrefix }32>`;
|
|
|
|
|
|
|
+ textureType = `texture${ multisampled }_2d<${ componentPrefix }32>`;
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1671,15 +1692,23 @@ ${ flowData.code }
|
|
|
} else if ( uniform.type === 'buffer' || uniform.type === 'storageBuffer' || uniform.type === 'indirectStorageBuffer' ) {
|
|
} else if ( uniform.type === 'buffer' || uniform.type === 'storageBuffer' || uniform.type === 'indirectStorageBuffer' ) {
|
|
|
|
|
|
|
|
const bufferNode = uniform.node;
|
|
const bufferNode = uniform.node;
|
|
|
- const bufferType = this.getType( bufferNode.bufferType );
|
|
|
|
|
|
|
+ const bufferType = this.getType( bufferNode.getNodeType( this ) );
|
|
|
const bufferCount = bufferNode.bufferCount;
|
|
const bufferCount = bufferNode.bufferCount;
|
|
|
-
|
|
|
|
|
const bufferCountSnippet = bufferCount > 0 && uniform.type === 'buffer' ? ', ' + bufferCount : '';
|
|
const bufferCountSnippet = bufferCount > 0 && uniform.type === 'buffer' ? ', ' + bufferCount : '';
|
|
|
- const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${bufferType}>` : `${bufferType}`;
|
|
|
|
|
- const bufferSnippet = `\t${ uniform.name } : array< ${ bufferTypeSnippet }${ bufferCountSnippet } >\n`;
|
|
|
|
|
const bufferAccessMode = bufferNode.isStorageBufferNode ? `storage, ${ this.getStorageAccess( bufferNode, shaderStage ) }` : 'uniform';
|
|
const bufferAccessMode = bufferNode.isStorageBufferNode ? `storage, ${ this.getStorageAccess( bufferNode, shaderStage ) }` : 'uniform';
|
|
|
|
|
|
|
|
- bufferSnippets.push( this._getWGSLStructBinding( 'NodeBuffer_' + bufferNode.id, bufferSnippet, bufferAccessMode, uniformIndexes.binding ++, uniformIndexes.group ) );
|
|
|
|
|
|
|
+ if ( this.isCustomStruct( uniform ) ) {
|
|
|
|
|
+
|
|
|
|
|
+ bufferSnippets.push( `@binding( ${ uniformIndexes.binding ++ } ) @group( ${ uniformIndexes.group } ) var<${ bufferAccessMode }> ${ uniform.name } : ${ bufferType };` );
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+
|
|
|
|
|
+ const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${ bufferType }>` : `${ bufferType }`;
|
|
|
|
|
+ const bufferSnippet = `\tvalue : array< ${ bufferTypeSnippet }${ bufferCountSnippet } >`;
|
|
|
|
|
+
|
|
|
|
|
+ bufferSnippets.push( this._getWGSLStructBinding( uniform.name, bufferSnippet, bufferAccessMode, uniformIndexes.binding ++, uniformIndexes.group ) );
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
|
@@ -1725,6 +1754,8 @@ ${ flowData.code }
|
|
|
|
|
|
|
|
for ( const shaderStage in shadersData ) {
|
|
for ( const shaderStage in shadersData ) {
|
|
|
|
|
|
|
|
|
|
+ this.shaderStage = shaderStage;
|
|
|
|
|
+
|
|
|
const stageData = shadersData[ shaderStage ];
|
|
const stageData = shadersData[ shaderStage ];
|
|
|
stageData.uniforms = this.getUniforms( shaderStage );
|
|
stageData.uniforms = this.getUniforms( shaderStage );
|
|
|
stageData.attributes = this.getAttributes( shaderStage );
|
|
stageData.attributes = this.getAttributes( shaderStage );
|
|
@@ -1773,7 +1804,8 @@ ${ flowData.code }
|
|
|
|
|
|
|
|
if ( isOutputStruct ) {
|
|
if ( isOutputStruct ) {
|
|
|
|
|
|
|
|
- stageData.returnType = outputNode.nodeType;
|
|
|
|
|
|
|
+ stageData.returnType = outputNode.getNodeType( this );
|
|
|
|
|
+ stageData.structs += 'var<private> output : ' + stageData.returnType + ';';
|
|
|
|
|
|
|
|
flow += `return ${ flowSlotData.result };`;
|
|
flow += `return ${ flowSlotData.result };`;
|
|
|
|
|
|
|
@@ -1787,7 +1819,7 @@ ${ flowData.code }
|
|
|
|
|
|
|
|
stageData.returnType = 'OutputStruct';
|
|
stageData.returnType = 'OutputStruct';
|
|
|
stageData.structs += this._getWGSLStruct( 'OutputStruct', structSnippet );
|
|
stageData.structs += this._getWGSLStruct( 'OutputStruct', structSnippet );
|
|
|
- stageData.structs += '\nvar<private> output : OutputStruct;\n\n';
|
|
|
|
|
|
|
+ stageData.structs += '\nvar<private> output : OutputStruct;';
|
|
|
|
|
|
|
|
flow += `output.color = ${ flowSlotData.result };\n\n\treturn output;`;
|
|
flow += `output.color = ${ flowSlotData.result };\n\n\treturn output;`;
|
|
|
|
|
|
|
@@ -1801,9 +1833,10 @@ ${ flowData.code }
|
|
|
|
|
|
|
|
stageData.flow = flow;
|
|
stageData.flow = flow;
|
|
|
|
|
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ this.shaderStage = null;
|
|
|
|
|
+
|
|
|
if ( this.material !== null ) {
|
|
if ( this.material !== null ) {
|
|
|
|
|
|
|
|
this.vertexShader = this._getWGSLVertexCode( shadersData.vertex );
|
|
this.vertexShader = this._getWGSLVertexCode( shadersData.vertex );
|
|
@@ -1941,6 +1974,9 @@ ${ flowData.code }
|
|
|
// directives
|
|
// directives
|
|
|
${shaderData.directives}
|
|
${shaderData.directives}
|
|
|
|
|
|
|
|
|
|
+// structs
|
|
|
|
|
+${shaderData.structs}
|
|
|
|
|
+
|
|
|
// uniforms
|
|
// uniforms
|
|
|
${shaderData.uniforms}
|
|
${shaderData.uniforms}
|
|
|
|
|
|
|
@@ -1980,12 +2016,12 @@ fn main( ${shaderData.attributes} ) -> VaryingsStruct {
|
|
|
// global
|
|
// global
|
|
|
${ diagnostics }
|
|
${ diagnostics }
|
|
|
|
|
|
|
|
-// uniforms
|
|
|
|
|
-${shaderData.uniforms}
|
|
|
|
|
-
|
|
|
|
|
// structs
|
|
// structs
|
|
|
${shaderData.structs}
|
|
${shaderData.structs}
|
|
|
|
|
|
|
|
|
|
+// uniforms
|
|
|
|
|
+${shaderData.uniforms}
|
|
|
|
|
+
|
|
|
// codes
|
|
// codes
|
|
|
${shaderData.codes}
|
|
${shaderData.codes}
|
|
|
|
|
|
|
@@ -2023,6 +2059,9 @@ var<private> instanceIndex : u32;
|
|
|
// locals
|
|
// locals
|
|
|
${shaderData.scopedArrays}
|
|
${shaderData.scopedArrays}
|
|
|
|
|
|
|
|
|
|
+// structs
|
|
|
|
|
+${shaderData.structs}
|
|
|
|
|
+
|
|
|
// uniforms
|
|
// uniforms
|
|
|
${shaderData.uniforms}
|
|
${shaderData.uniforms}
|
|
|
|
|
|
|
@@ -2080,8 +2119,8 @@ ${vars}
|
|
|
const structSnippet = this._getWGSLStruct( structName, vars );
|
|
const structSnippet = this._getWGSLStruct( structName, vars );
|
|
|
|
|
|
|
|
return `${structSnippet}
|
|
return `${structSnippet}
|
|
|
-@binding( ${binding} ) @group( ${group} )
|
|
|
|
|
-var<${access}> ${name} : ${structName};`;
|
|
|
|
|
|
|
+@binding( ${ binding } ) @group( ${ group } )
|
|
|
|
|
+var<${access}> ${ name } : ${ structName };`;
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|