|
@@ -16,6 +16,10 @@ import CodeNode from 'three-nodes/core/CodeNode.js';
|
|
|
|
|
|
import { NodeMaterial } from 'three-nodes/materials/Materials.js';
|
|
import { NodeMaterial } from 'three-nodes/materials/Materials.js';
|
|
|
|
|
|
|
|
+const supports = {
|
|
|
|
+ instance: true
|
|
|
|
+};
|
|
|
|
+
|
|
const wgslTypeLib = {
|
|
const wgslTypeLib = {
|
|
float: 'f32',
|
|
float: 'f32',
|
|
int: 'i32',
|
|
int: 'i32',
|
|
@@ -50,7 +54,8 @@ const wgslTypeLib = {
|
|
|
|
|
|
const wgslMethods = {
|
|
const wgslMethods = {
|
|
dFdx: 'dpdx',
|
|
dFdx: 'dpdx',
|
|
- dFdy: 'dpdy'
|
|
|
|
|
|
+ dFdy: 'dpdy',
|
|
|
|
+ inversesqrt: 'inverseSqrt'
|
|
};
|
|
};
|
|
|
|
|
|
const wgslPolyfill = {
|
|
const wgslPolyfill = {
|
|
@@ -75,13 +80,6 @@ fn repeatWrapping( uv : vec2<f32>, dimension : vec2<i32> ) -> vec2<i32> {
|
|
|
|
|
|
return ( ( uvScaled % dimension ) + dimension ) % dimension;
|
|
return ( ( uvScaled % dimension ) + dimension ) % dimension;
|
|
|
|
|
|
-}
|
|
|
|
-` ),
|
|
|
|
- inversesqrt: new CodeNode( `
|
|
|
|
-fn inversesqrt( x : f32 ) -> f32 {
|
|
|
|
-
|
|
|
|
- return 1.0 / sqrt( x );
|
|
|
|
-
|
|
|
|
}
|
|
}
|
|
` )
|
|
` )
|
|
};
|
|
};
|
|
@@ -100,6 +98,8 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
this.uniformsGroup = {};
|
|
this.uniformsGroup = {};
|
|
|
|
|
|
|
|
+ this.builtins = new Set();
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
build() {
|
|
build() {
|
|
@@ -173,7 +173,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
} else if ( type === 'buffer' ) {
|
|
} else if ( type === 'buffer' ) {
|
|
|
|
|
|
- return `NodeBuffer.${name}`;
|
|
|
|
|
|
+ return `NodeBuffer_${node.node.id}.${name}`;
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
@@ -240,10 +240,9 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
} else if ( type === 'buffer' ) {
|
|
} else if ( type === 'buffer' ) {
|
|
|
|
|
|
- const buffer = new WebGPUUniformBuffer( 'NodeBuffer', node.value );
|
|
|
|
|
|
+ const buffer = new WebGPUUniformBuffer( 'NodeBuffer_' + node.id, node.value );
|
|
|
|
|
|
// add first textures in sequence and group for last
|
|
// add first textures in sequence and group for last
|
|
const lastBinding = bindings[ bindings.length - 1 ];
|
|
const lastBinding = bindings[ bindings.length - 1 ];
|
|
@@ -315,12 +314,30 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ getInstanceIndex( shaderStage = this.shaderStage ) {
|
|
|
|
+
|
|
|
|
+ this.builtins.add( 'instance_index' );
|
|
|
|
+
|
|
|
|
+ if ( shaderStage === 'vertex' ) {
|
|
|
|
+
|
|
|
|
+ return 'instanceIndex';
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
getAttributes( shaderStage ) {
|
|
getAttributes( shaderStage ) {
|
|
|
|
|
|
const snippets = [];
|
|
const snippets = [];
|
|
|
|
|
|
if ( shaderStage === 'vertex' ) {
|
|
if ( shaderStage === 'vertex' ) {
|
|
|
|
|
|
|
|
+ if ( this.builtins.has( 'instance_index' ) ) {
|
|
|
|
+
|
|
|
|
+ snippets.push( `@builtin( instance_index ) instanceIndex : u32` );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
const attributes = this.attributes;
|
|
const attributes = this.attributes;
|
|
const length = attributes.length;
|
|
const length = attributes.length;
|
|
|
|
|
|
@@ -394,7 +411,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
const code = snippets.join( ',\n\t' );
|
|
const code = snippets.join( ',\n\t' );
|
|
|
|
|
|
- return shaderStage === 'vertex' ? this._getWGSLStruct( 'NodeVarysStruct', code ) : code;
|
|
|
|
|
|
+ return shaderStage === 'vertex' ? this._getWGSLStruct( 'NodeVarysStruct', '\t' + code ) : code;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -438,7 +455,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
const bufferSnippet = `\t${uniform.name} : array< ${bufferType}, ${bufferCount} >\n`;
|
|
const bufferSnippet = `\t${uniform.name} : array< ${bufferType}, ${bufferCount} >\n`;
|
|
|
|
|
|
- bufferSnippets.push( this._getWGSLUniforms( 'NodeBuffer', bufferSnippet, index ++ ) );
|
|
|
|
|
|
+ bufferSnippets.push( this._getWGSLUniforms( 'NodeBuffer_' + bufferNode.id, bufferSnippet, index ++ ) );
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
@@ -461,7 +478,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
}
|
|
}
|
|
|
|
|
|
let code = bindingSnippets.join( '\n' );
|
|
let code = bindingSnippets.join( '\n' );
|
|
- code += bufferSnippets.join( ',\n' );
|
|
|
|
|
|
+ code += bufferSnippets.join( '\n' );
|
|
|
|
|
|
if ( groupSnippets.length > 0 ) {
|
|
if ( groupSnippets.length > 0 ) {
|
|
|
|
|
|
@@ -555,6 +572,12 @@ class WebGPUNodeBuilder extends NodeBuilder {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ isAvailable( name ) {
|
|
|
|
+
|
|
|
|
+ return supports[ name ] === true;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
_include( name ) {
|
|
_include( name ) {
|
|
|
|
|
|
wgslPolyfill[ name ].build( this );
|
|
wgslPolyfill[ name ].build( this );
|