Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/nodes/core/AssignNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ class AssignNode extends TempNode {
*/
this.sourceNode = sourceNode;

/**
* This flag can be used for type testing.
*
* @type {boolean}
* @readonly
* @default true
*/
this.isAssignNode = true;

}

/**
Expand Down
18 changes: 14 additions & 4 deletions src/nodes/core/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -506,11 +506,21 @@ class Node extends EventDispatcher {
* This stage analyzes the node hierarchy and ensures descendent nodes are built.
*
* @param {NodeBuilder} builder - The current node builder.
* @param {?Node} output - The target output node.
*/
analyze( builder ) {
analyze( builder, output = null ) {

const usageCount = builder.increaseUsage( this );

if ( this.parents === true ) {

const nodeData = builder.getDataFromNode( this, 'any' );
nodeData.stages = nodeData.stages || {};
nodeData.stages[ builder.shaderStage ] = nodeData.stages[ builder.shaderStage ] || [];
nodeData.stages[ builder.shaderStage ].push( output );

}

if ( usageCount === 1 ) {

// node flow children
Expand All @@ -521,7 +531,7 @@ class Node extends EventDispatcher {

if ( childNode && childNode.isNode === true ) {

childNode.build( builder );
childNode.build( builder, this );

}

Expand Down Expand Up @@ -600,7 +610,7 @@ class Node extends EventDispatcher {
* - **generate**: Generates the shader code for the node. Returns the generated shader string.
*
* @param {NodeBuilder} builder - The current node builder.
* @param {?string} [output=null] - Can be used to define the output type.
* @param {string|Node|null} [output=null] - Can be used to define the output type.
* @return {Node|string|null} The result of the build process, depending on the build stage.
*/
build( builder, output = null ) {
Expand Down Expand Up @@ -669,7 +679,7 @@ class Node extends EventDispatcher {

} else if ( buildStage === 'analyze' ) {

this.analyze( builder );
this.analyze( builder, output );

} else if ( buildStage === 'generate' ) {

Expand Down
40 changes: 33 additions & 7 deletions src/nodes/core/NodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -2285,27 +2285,53 @@ class NodeBuilder {
* @param {Node} node - The node to execute.
* @param {?string} output - Expected output type. For example 'vec3'.
* @param {?string} propertyName - The property name to assign the result.
* @return {Object}
* @return {Object|Node|null} The code flow or node.build() result.
*/
flowNodeFromShaderStage( shaderStage, node, output = null, propertyName = null ) {

const previousTab = this.tab;
const previousCache = this.cache;
const previousShaderStage = this.shaderStage;
const previousContext = this.context;

this.setShaderStage( shaderStage );

const flowData = this.flowChildNode( node, output );
const context = { ...this.context };
delete context.nodeBlock;

if ( propertyName !== null ) {
this.cache = this.globalCache;
this.tab = '\t';
this.context = context;

flowData.code += `${ this.tab + propertyName } = ${ flowData.result };\n`;
let result = null;

}
if ( this.buildStage === 'generate' ) {

const flowData = this.flowChildNode( node, output );

if ( propertyName !== null ) {

this.flowCode[ shaderStage ] = this.flowCode[ shaderStage ] + flowData.code;
flowData.code += `${ this.tab + propertyName } = ${ flowData.result };\n`;

}

this.flowCode[ shaderStage ] = this.flowCode[ shaderStage ] + flowData.code;

result = flowData;

} else {

result = node.build( this );

}

this.setShaderStage( previousShaderStage );

return flowData;
this.cache = previousCache;
this.tab = previousTab;
this.context = previousContext;

return result;

}

Expand Down
25 changes: 24 additions & 1 deletion src/nodes/core/StackNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,32 @@ class StackNode extends Node {

setCurrentStack( this );

const buildStage = builder.buildStage;

for ( const node of this.nodes ) {

node.build( builder, 'void' );
if ( buildStage === 'setup' ) {

node.build( builder );

} else if ( buildStage === 'analyze' ) {

node.build( builder, this );

} else if ( buildStage === 'generate' ) {

const stages = builder.getDataFromNode( node, 'any' ).stages;
const parents = stages && stages[ builder.shaderStage ];

if ( node.isVarNode && parents && parents.length === 1 && parents[ 0 ] && parents[ 0 ].isStackNode ) {

continue; // skip var nodes that are only used in .toVarying()

}

node.build( builder, 'void' );

}

}

Expand Down
9 changes: 9 additions & 0 deletions src/nodes/core/VarNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ class VarNode extends Node {
*/
this.readOnly = readOnly;

/**
*
* Add this flag to the node system to indicate that this node require parents.
*
* @type {boolean}
* @default true
*/
this.parents = true;

}

getMemberType( builder, name ) {
Expand Down
5 changes: 4 additions & 1 deletion src/nodes/core/VaryingNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class VaryingNode extends Node {

this.interpolationType = type;
this.interpolationSampling = sampling;

return this;

}
Expand Down Expand Up @@ -150,13 +151,15 @@ class VaryingNode extends Node {

this.setupVarying( builder );

builder.flowNodeFromShaderStage( NodeShaderStage.VERTEX, this.node );

}

analyze( builder ) {

this.setupVarying( builder );

return this.node.analyze( builder );
builder.flowNodeFromShaderStage( NodeShaderStage.VERTEX, this.node );

}

Expand Down