|
@@ -5,62 +5,62 @@ const VERSION = '1';
|
|
class NodeBuilder {
|
|
class NodeBuilder {
|
|
|
|
|
|
constructor( material, renderer ) {
|
|
constructor( material, renderer ) {
|
|
-
|
|
|
|
|
|
+
|
|
this.material = material;
|
|
this.material = material;
|
|
this.renderer = renderer;
|
|
this.renderer = renderer;
|
|
-
|
|
|
|
|
|
+
|
|
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.nodesData = new WeakMap();
|
|
this.nodesData = new WeakMap();
|
|
-
|
|
|
|
|
|
+
|
|
this.shaderStage = null;
|
|
this.shaderStage = null;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
addSlot( shader, slot ) {
|
|
addSlot( shader, slot ) {
|
|
-
|
|
|
|
|
|
+
|
|
this.slots[ shader ].push( slot );
|
|
this.slots[ shader ].push( slot );
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
define( shader, name, value = '' ) {
|
|
define( shader, name, value = '' ) {
|
|
-
|
|
|
|
|
|
+
|
|
this.defines[ shader ][ name ] = value;
|
|
this.defines[ shader ][ name ] = value;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
generateVec2( x, y ) {
|
|
generateVec2( x, y ) {
|
|
-
|
|
|
|
|
|
+
|
|
return `vec2( ${x}, ${y})`;
|
|
return `vec2( ${x}, ${y})`;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
generateVec3( x, y, z ) {
|
|
generateVec3( x, y, z ) {
|
|
-
|
|
|
|
|
|
+
|
|
return `vec3( ${x}, ${y}, ${z} )`;
|
|
return `vec3( ${x}, ${y}, ${z} )`;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
generateVec4( x, y, z, w ) {
|
|
generateVec4( x, y, z, w ) {
|
|
-
|
|
|
|
|
|
+
|
|
return `vec4( ${x}, ${y}, ${z}, ${w} )`;
|
|
return `vec4( ${x}, ${y}, ${z}, ${w} )`;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
generateFloat( value ) {
|
|
generateFloat( value ) {
|
|
-
|
|
|
|
|
|
+
|
|
return value + ( value % 1 ? '' : '.0' );
|
|
return value + ( value % 1 ? '' : '.0' );
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
getUniformNSName( nodeUniform ) {
|
|
getUniformNSName( nodeUniform ) {
|
|
-
|
|
|
|
|
|
+
|
|
return nodeUniform.name;
|
|
return nodeUniform.name;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
getTypeLength( type ) {
|
|
getTypeLength( type ) {
|
|
|
|
|
|
if ( type === 'float' ) return 1;
|
|
if ( type === 'float' ) return 1;
|
|
@@ -71,121 +71,121 @@ class NodeBuilder {
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
getDataFromNode( node, shaderStage = null ) {
|
|
getDataFromNode( node, shaderStage = null ) {
|
|
-
|
|
|
|
|
|
+
|
|
let nodeData = this.nodesData.get( node );
|
|
let nodeData = this.nodesData.get( node );
|
|
-
|
|
|
|
|
|
+
|
|
if ( nodeData === undefined ) {
|
|
if ( nodeData === undefined ) {
|
|
-
|
|
|
|
|
|
+
|
|
nodeData = { vertex: {}, fragment: {} };
|
|
nodeData = { vertex: {}, fragment: {} };
|
|
-
|
|
|
|
|
|
+
|
|
this.nodesData.set( node, nodeData );
|
|
this.nodesData.set( node, nodeData );
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return shaderStage ? nodeData[ shaderStage ] : nodeData;
|
|
return shaderStage ? nodeData[ shaderStage ] : nodeData;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
getUniformFromNode( node, shaderStage, type ) {
|
|
getUniformFromNode( node, shaderStage, type ) {
|
|
-
|
|
|
|
|
|
+
|
|
const nodeData = this.getDataFromNode( node, shaderStage );
|
|
const nodeData = this.getDataFromNode( node, shaderStage );
|
|
-
|
|
|
|
|
|
+
|
|
let nodeUniform = nodeData.uniform;
|
|
let nodeUniform = nodeData.uniform;
|
|
-
|
|
|
|
|
|
+
|
|
if ( nodeUniform === undefined ) {
|
|
if ( nodeUniform === undefined ) {
|
|
-
|
|
|
|
- const uniforms = this.uniforms[shaderStage];
|
|
|
|
|
|
+
|
|
|
|
+ const uniforms = this.uniforms[ shaderStage ];
|
|
const index = uniforms.length;
|
|
const index = uniforms.length;
|
|
-
|
|
|
|
|
|
+
|
|
nodeUniform = new NodeUniform( 'nodeU' + index, type, node );
|
|
nodeUniform = new NodeUniform( 'nodeU' + index, type, node );
|
|
-
|
|
|
|
|
|
+
|
|
uniforms.push( nodeUniform );
|
|
uniforms.push( nodeUniform );
|
|
-
|
|
|
|
|
|
+
|
|
nodeData.uniform = nodeUniform;
|
|
nodeData.uniform = nodeUniform;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return nodeUniform;
|
|
return nodeUniform;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
/*
|
|
/*
|
|
analyzeNode( node ) {
|
|
analyzeNode( node ) {
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|
|
*/
|
|
*/
|
|
-
|
|
|
|
|
|
+
|
|
flowNode( node, output ) {
|
|
flowNode( node, output ) {
|
|
-
|
|
|
|
|
|
+
|
|
let flowData = {};
|
|
let flowData = {};
|
|
flowData.result = node.build( this, output );
|
|
flowData.result = node.build( this, output );
|
|
-
|
|
|
|
|
|
+
|
|
return flowData;
|
|
return flowData;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
buildDefines( shader ) {
|
|
buildDefines( shader ) {
|
|
-
|
|
|
|
|
|
+
|
|
const defines = this.defines[ shader ];
|
|
const defines = this.defines[ shader ];
|
|
-
|
|
|
|
|
|
+
|
|
let code = '';
|
|
let code = '';
|
|
-
|
|
|
|
|
|
+
|
|
for ( let name in defines ) {
|
|
for ( let name in defines ) {
|
|
-
|
|
|
|
- code += `#define ${name} ${defines[name]}\n`;
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ code += `#define ${name} ${defines[ name ]}\n`;
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return code;
|
|
return code;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
build( shaderStage ) {
|
|
build( shaderStage ) {
|
|
-
|
|
|
|
|
|
+
|
|
this.shaderStage = shaderStage;
|
|
this.shaderStage = shaderStage;
|
|
-
|
|
|
|
|
|
+
|
|
const slots = this.slots[ shaderStage ];
|
|
const slots = this.slots[ shaderStage ];
|
|
const uniforms = this.uniforms[ shaderStage ];
|
|
const uniforms = this.uniforms[ shaderStage ];
|
|
-
|
|
|
|
|
|
+
|
|
if ( slots.length ) {
|
|
if ( slots.length ) {
|
|
-
|
|
|
|
|
|
+
|
|
this.define( shaderStage, 'NODE', VERSION );
|
|
this.define( shaderStage, 'NODE', VERSION );
|
|
-
|
|
|
|
- for( let i = 0; i < slots.length; i++) {
|
|
|
|
-
|
|
|
|
- let slot = slots[i];
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ for ( let i = 0; i < slots.length; i ++ ) {
|
|
|
|
+
|
|
|
|
+ let slot = slots[ i ];
|
|
|
|
+
|
|
let flowData = this.flowNode( slot.node, slot.output );
|
|
let flowData = this.flowNode( slot.node, slot.output );
|
|
-
|
|
|
|
|
|
+
|
|
this.define( shaderStage, `NODE_${slot.name}`, flowData.result );
|
|
this.define( shaderStage, `NODE_${slot.name}`, flowData.result );
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
let uniformsCode = '';
|
|
let uniformsCode = '';
|
|
-
|
|
|
|
- for( let i = 0; i < uniforms.length; i++) {
|
|
|
|
-
|
|
|
|
- let uniform = uniforms[i];
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ for ( let i = 0; i < uniforms.length; i ++ ) {
|
|
|
|
+
|
|
|
|
+ let uniform = uniforms[ i ];
|
|
|
|
+
|
|
uniformsCode += `${uniform.type} ${uniform.name}; `;
|
|
uniformsCode += `${uniform.type} ${uniform.name}; `;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
this.define( shaderStage, 'NODE_UNIFORMS', uniformsCode );
|
|
this.define( shaderStage, 'NODE_UNIFORMS', uniformsCode );
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
let defines = this.buildDefines( shaderStage );
|
|
let defines = this.buildDefines( shaderStage );
|
|
-
|
|
|
|
|
|
+
|
|
return {
|
|
return {
|
|
defines
|
|
defines
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
format( code, fromType, toType ) {
|
|
format( code, fromType, toType ) {
|
|
|
|
|
|
const typeToType = `${fromType} -> ${toType}`;
|
|
const typeToType = `${fromType} -> ${toType}`;
|
|
@@ -193,7 +193,7 @@ class NodeBuilder {
|
|
switch ( typeToType ) {
|
|
switch ( typeToType ) {
|
|
|
|
|
|
case 'float -> vec3' : return `vec3( ${code} )`;
|
|
case 'float -> vec3' : return `vec3( ${code} )`;
|
|
-
|
|
|
|
|
|
+
|
|
case 'vec3 -> float' : return `${code}.x`;
|
|
case 'vec3 -> float' : return `${code}.x`;
|
|
|
|
|
|
}
|
|
}
|
|
@@ -201,7 +201,7 @@ class NodeBuilder {
|
|
return code;
|
|
return code;
|
|
|
|
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
export default NodeBuilder;
|
|
export default NodeBuilder;
|