Skip to content

TSL: Improve build stages #31156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 24, 2025
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
13 changes: 6 additions & 7 deletions src/nodes/accessors/Object3DNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,9 @@ class Object3DNode extends Node {
/**
* Holds the value of the node as a uniform.
*
* @private
* @type {UniformNode}
*/
this._uniformNode = new UniformNode( null );
this.uniformNode = new UniformNode( null );

}

Expand Down Expand Up @@ -104,7 +103,7 @@ class Object3DNode extends Node {
update( frame ) {

const object = this.object3d;
const uniformNode = this._uniformNode;
const uniformNode = this.uniformNode;
const scope = this.scope;

if ( scope === Object3DNode.WORLD_MATRIX ) {
Expand Down Expand Up @@ -165,19 +164,19 @@ class Object3DNode extends Node {

if ( scope === Object3DNode.WORLD_MATRIX ) {

this._uniformNode.nodeType = 'mat4';
this.uniformNode.nodeType = 'mat4';

} else if ( scope === Object3DNode.POSITION || scope === Object3DNode.VIEW_POSITION || scope === Object3DNode.DIRECTION || scope === Object3DNode.SCALE ) {

this._uniformNode.nodeType = 'vec3';
this.uniformNode.nodeType = 'vec3';

} else if ( scope === Object3DNode.RADIUS ) {

this._uniformNode.nodeType = 'float';
this.uniformNode.nodeType = 'float';

}

return this._uniformNode.build( builder );
return this.uniformNode.build( builder );

}

Expand Down
23 changes: 18 additions & 5 deletions src/nodes/core/AssignNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,25 @@ class AssignNode extends TempNode {

}

generate( builder, output ) {
setup( builder ) {

const { targetNode, sourceNode } = this;

const properties = builder.getNodeProperties( this );
properties.sourceNode = sourceNode;
properties.targetNode = targetNode.context( { assign: true } );

}

generate( builder, output ) {

const { targetNode, sourceNode } = builder.getNodeProperties( this );

const needsSplitAssign = this.needsSplitAssign( builder );

const targetType = targetNode.getNodeType( builder );

const target = targetNode.context( { assign: true } ).build( builder );
const target = targetNode.build( builder );
const source = sourceNode.build( builder, targetType );

const sourceType = sourceNode.getNodeType( builder );
Expand All @@ -127,11 +137,14 @@ class AssignNode extends TempNode {

builder.addLineFlowCode( `${ sourceProperty } = ${ source }`, this );

const targetRoot = targetNode.node.context( { assign: true } ).build( builder );
const splitNode = targetNode.node;
const splitTargetNode = splitNode.node.context( { assign: true } );

const targetRoot = splitTargetNode.build( builder );

for ( let i = 0; i < targetNode.components.length; i ++ ) {
for ( let i = 0; i < splitNode.components.length; i ++ ) {

const component = targetNode.components[ i ];
const component = splitNode.components[ i ];

builder.addLineFlowCode( `${ targetRoot }.${ component } = ${ sourceProperty }[ ${ i } ]`, this );

Expand Down
29 changes: 29 additions & 0 deletions src/nodes/core/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import { getNodeChildren, getCacheKey, hash } from './NodeUtils.js';
import { EventDispatcher } from '../../core/EventDispatcher.js';
import { MathUtils } from '../../math/MathUtils.js';

const _parentBuildStage = {
analyze: 'setup',
generate: 'analyze'
};

let _nodeId = 0;

/**
Expand Down Expand Up @@ -623,6 +628,30 @@ class Node extends EventDispatcher {

}

//

const nodeData = builder.getDataFromNode( this );
nodeData.buildStages = nodeData.buildStages || {};
nodeData.buildStages[ builder.buildStage ] = true;

const parentBuildStage = _parentBuildStage[ builder.buildStage ];

if ( parentBuildStage && nodeData.buildStages[ parentBuildStage ] !== true ) {

// force parent build stage (setup or analyze)

const previousBuildStage = builder.getBuildStage();

builder.setBuildStage( parentBuildStage );

this.build( builder );

builder.setBuildStage( previousBuildStage );

}

//

builder.addNode( this );
builder.addChain( this );

Expand Down
6 changes: 4 additions & 2 deletions src/nodes/lighting/LightsNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,16 @@ class LightsNode extends Node {

analyze( builder ) {

const properties = builder.getDataFromNode( this );
const properties = builder.getNodeProperties( this );

for ( const node of properties.nodes ) {

node.build( builder );

}

properties.outputNode.build( builder );

}

/**
Expand Down Expand Up @@ -329,7 +331,7 @@ class LightsNode extends Node {
const context = builder.context;
const lightingModel = context.lightingModel;

const properties = builder.getDataFromNode( this );
const properties = builder.getNodeProperties( this );

if ( lightingModel ) {

Expand Down
68 changes: 48 additions & 20 deletions src/nodes/math/MathNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,26 +160,31 @@ class MathNode extends TempNode {

}

generate( builder, output ) {
setup( builder ) {

let method = this.method;
const { aNode, bNode, method } = this;

const type = this.getNodeType( builder );
const inputType = this.getInputType( builder );
let outputNode = null;

const a = this.aNode;
const b = this.bNode;
const c = this.cNode;
if ( method === MathNode.ONE_MINUS ) {

const coordinateSystem = builder.renderer.coordinateSystem;
outputNode = sub( 1.0, aNode );

if ( method === MathNode.TRANSFORM_DIRECTION ) {
} else if ( method === MathNode.RECIPROCAL ) {

outputNode = div( 1.0, aNode );

} else if ( method === MathNode.DIFFERENCE ) {

outputNode = abs( sub( aNode, bNode ) );

} else if ( method === MathNode.TRANSFORM_DIRECTION ) {

// dir can be either a direction vector or a normal vector
// upper-left 3x3 of matrix is assumed to be orthogonal

let tA = a;
let tB = b;
let tA = aNode;
let tB = bNode;

if ( builder.isMatrix( tA.getNodeType( builder ) ) ) {

Expand All @@ -193,23 +198,46 @@ class MathNode extends TempNode {

const mulNode = mul( tA, tB ).xyz;

return normalize( mulNode ).build( builder, output );
outputNode = normalize( mulNode );

} else if ( method === MathNode.NEGATE ) {
}

return builder.format( '( - ' + a.build( builder, inputType ) + ' )', type, output );
if ( outputNode !== null ) {

} else if ( method === MathNode.ONE_MINUS ) {
return outputNode;

return sub( 1.0, a ).build( builder, output );
} else {

} else if ( method === MathNode.RECIPROCAL ) {
return super.setup( builder );

return div( 1.0, a ).build( builder, output );
}

} else if ( method === MathNode.DIFFERENCE ) {
}

return abs( sub( a, b ) ).build( builder, output );
generate( builder, output ) {

const properties = builder.getNodeProperties( this );

if ( properties.outputNode ) {

return super.generate( builder, output );

}

let method = this.method;

const type = this.getNodeType( builder );
const inputType = this.getInputType( builder );

const a = this.aNode;
const b = this.bNode;
const c = this.cNode;

const coordinateSystem = builder.renderer.coordinateSystem;

if ( method === MathNode.NEGATE ) {

return builder.format( '( - ' + a.build( builder, inputType ) + ' )', type, output );

} else {

Expand Down
9 changes: 4 additions & 5 deletions src/nodes/math/OperatorNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class OperatorNode extends TempNode {
const bNode = this.bNode;

const typeA = aNode.getNodeType( builder );
const typeB = typeof bNode !== 'undefined' ? bNode.getNodeType( builder ) : null;
const typeB = bNode ? bNode.getNodeType( builder ) : null;

if ( typeA === 'void' || typeB === 'void' ) {

Expand Down Expand Up @@ -191,8 +191,7 @@ class OperatorNode extends TempNode {

const op = this.op;

const aNode = this.aNode;
const bNode = this.bNode;
const { aNode, bNode } = this;

const type = this.getNodeType( builder );

Expand All @@ -202,7 +201,7 @@ class OperatorNode extends TempNode {
if ( type !== 'void' ) {

typeA = aNode.getNodeType( builder );
typeB = typeof bNode !== 'undefined' ? bNode.getNodeType( builder ) : null;
typeB = bNode ? bNode.getNodeType( builder ) : null;

if ( op === '<' || op === '>' || op === '<=' || op === '>=' || op === '==' || op === '!=' ) {

Expand Down Expand Up @@ -288,7 +287,7 @@ class OperatorNode extends TempNode {
}

const a = aNode.build( builder, typeA );
const b = typeof bNode !== 'undefined' ? bNode.build( builder, typeB ) : null;
const b = bNode ? bNode.build( builder, typeB ) : null;

const fnOpSnippet = builder.getFunctionOperator( op );

Expand Down