Skip to content

Commit d8e6aa3

Browse files
authored
TSL: Move ShaderNode to tslFn() (#26311)
* Move `ShaderNode` to `fn()` Move `func()` -> `wgslFn()` Move `shader()` -> `fn()` * NodeMaterialLoader: Fix createMaterialFromType() * revisions * return stack output if is void * SkinningNode: Move assign() to stack * Nodes: Vertex stage revision and rename fn() -> tslFn() * cleanup
1 parent a2adc8b commit d8e6aa3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+252
-221
lines changed

examples/jsm/nodes/Nodes.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ export { default as ViewportDepthNode, viewZToOrthographicDepth, orthographicDep
103103

104104
// code
105105
export { default as ExpressionNode, expression } from './code/ExpressionNode.js';
106-
export { default as CodeNode, code, js } from './code/CodeNode.js';
106+
export { default as CodeNode, code, js, wgsl, glsl } from './code/CodeNode.js';
107107
export { default as FunctionCallNode, call } from './code/FunctionCallNode.js';
108-
export { default as FunctionNode, func, fn } from './code/FunctionNode.js';
108+
export { default as FunctionNode, wgslFn, glslFn } from './code/FunctionNode.js';
109109
export { default as ScriptableNode, scriptable, global } from './code/ScriptableNode.js';
110110
export { default as ScriptableValueNode, scriptableValue } from './code/ScriptableValueNode.js';
111111

examples/jsm/nodes/accessors/InstanceNode.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@ class InstanceNode extends Node {
6060
builder.stack.assign( positionLocal, instancePosition );
6161
builder.stack.assign( normalLocal, instanceNormal );
6262

63-
return builder.stack;
64-
6563
}
6664

6765
}

examples/jsm/nodes/accessors/SkinningNode.js

Lines changed: 43 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Node, { addNodeClass } from '../core/Node.js';
22
import { NodeUpdateType } from '../core/constants.js';
3-
import { ShaderNode, nodeProxy } from '../shadernode/ShaderNode.js';
3+
import { nodeProxy } from '../shadernode/ShaderNode.js';
44
import { attribute } from '../core/AttributeNode.js';
55
import { uniform } from '../core/UniformNode.js';
66
import { add } from '../math/OperatorNode.js';
@@ -9,91 +9,72 @@ import { normalLocal } from './NormalNode.js';
99
import { positionLocal } from './PositionNode.js';
1010
import { tangentLocal } from './TangentNode.js';
1111

12-
const Skinning = new ShaderNode( ( inputs, {}, builder ) => {
12+
class SkinningNode extends Node {
1313

14-
const { index, weight, bindMatrix, bindMatrixInverse, boneMatrices } = inputs;
14+
constructor( skinnedMesh ) {
1515

16-
const boneMatX = boneMatrices.element( index.x );
17-
const boneMatY = boneMatrices.element( index.y );
18-
const boneMatZ = boneMatrices.element( index.z );
19-
const boneMatW = boneMatrices.element( index.w );
16+
super( 'void' );
2017

21-
// POSITION
18+
this.skinnedMesh = skinnedMesh;
2219

23-
const skinVertex = bindMatrix.mul( positionLocal );
20+
this.updateType = NodeUpdateType.OBJECT;
2421

25-
const skinned = add(
26-
boneMatX.mul( weight.x ).mul( skinVertex ),
27-
boneMatY.mul( weight.y ).mul( skinVertex ),
28-
boneMatZ.mul( weight.z ).mul( skinVertex ),
29-
boneMatW.mul( weight.w ).mul( skinVertex )
30-
);
22+
//
3123

32-
const skinPosition = bindMatrixInverse.mul( skinned ).xyz;
24+
this.skinIndexNode = attribute( 'skinIndex', 'uvec4' );
25+
this.skinWeightNode = attribute( 'skinWeight', 'vec4' );
3326

34-
// NORMAL
27+
this.bindMatrixNode = uniform( skinnedMesh.bindMatrix, 'mat4' );
28+
this.bindMatrixInverseNode = uniform( skinnedMesh.bindMatrixInverse, 'mat4' );
29+
this.boneMatricesNode = buffer( skinnedMesh.skeleton.boneMatrices, 'mat4', skinnedMesh.skeleton.bones.length );
3530

36-
let skinMatrix = add(
37-
weight.x.mul( boneMatX ),
38-
weight.y.mul( boneMatY ),
39-
weight.z.mul( boneMatZ ),
40-
weight.w.mul( boneMatW )
41-
);
31+
}
4232

43-
skinMatrix = bindMatrixInverse.mul( skinMatrix ).mul( bindMatrix );
33+
construct( builder ) {
4434

45-
const skinNormal = skinMatrix.transformDirection( normalLocal ).xyz;
35+
const { skinIndexNode, skinWeightNode, bindMatrixNode, bindMatrixInverseNode, boneMatricesNode } = this;
4636

47-
// ASSIGNS
37+
const boneMatX = boneMatricesNode.element( skinIndexNode.x );
38+
const boneMatY = boneMatricesNode.element( skinIndexNode.y );
39+
const boneMatZ = boneMatricesNode.element( skinIndexNode.z );
40+
const boneMatW = boneMatricesNode.element( skinIndexNode.w );
4841

49-
positionLocal.assign( skinPosition ).build( builder ); // @TODO: For some reason this doesn't work as stack.assign( positionLocal, skinPosition )?
50-
normalLocal.assign( skinNormal ).build( builder );
42+
// POSITION
5143

52-
if ( builder.hasGeometryAttribute( 'tangent' ) ) {
44+
const skinVertex = bindMatrixNode.mul( positionLocal );
5345

54-
tangentLocal.assign( skinNormal ).build( builder );
46+
const skinned = add(
47+
boneMatX.mul( skinWeightNode.x ).mul( skinVertex ),
48+
boneMatY.mul( skinWeightNode.y ).mul( skinVertex ),
49+
boneMatZ.mul( skinWeightNode.z ).mul( skinVertex ),
50+
boneMatW.mul( skinWeightNode.w ).mul( skinVertex )
51+
);
5552

56-
}
53+
const skinPosition = bindMatrixInverseNode.mul( skinned ).xyz;
5754

58-
} );
55+
// NORMAL
5956

60-
class SkinningNode extends Node {
57+
let skinMatrix = add(
58+
skinWeightNode.x.mul( boneMatX ),
59+
skinWeightNode.y.mul( boneMatY ),
60+
skinWeightNode.z.mul( boneMatZ ),
61+
skinWeightNode.w.mul( boneMatW )
62+
);
6163

62-
constructor( skinnedMesh ) {
64+
skinMatrix = bindMatrixInverseNode.mul( skinMatrix ).mul( bindMatrixNode );
6365

64-
super( 'void' );
66+
const skinNormal = skinMatrix.transformDirection( normalLocal ).xyz;
6567

66-
this.skinnedMesh = skinnedMesh;
68+
// ASSIGNS
6769

68-
this.updateType = NodeUpdateType.OBJECT;
70+
builder.stack.assign( positionLocal, skinPosition );
71+
builder.stack.assign( normalLocal, skinNormal );
6972

70-
//
73+
if ( builder.hasGeometryAttribute( 'tangent' ) ) {
7174

72-
this.skinIndexNode = attribute( 'skinIndex', 'uvec4' );
73-
this.skinWeightNode = attribute( 'skinWeight', 'vec4' );
74-
75-
this.bindMatrixNode = uniform( skinnedMesh.bindMatrix, 'mat4' );
76-
this.bindMatrixInverseNode = uniform( skinnedMesh.bindMatrixInverse, 'mat4' );
77-
this.boneMatricesNode = buffer( skinnedMesh.skeleton.boneMatrices, 'mat4', skinnedMesh.skeleton.bones.length );
78-
79-
}
75+
builder.stack.assign( tangentLocal, skinNormal );
8076

81-
generate( builder ) {
82-
83-
/*return new ShaderNode( ( {}, stack, builder ) => Skinning.call( {
84-
index: this.skinIndexNode,
85-
weight: this.skinWeightNode,
86-
bindMatrix: this.bindMatrixNode,
87-
bindMatrixInverse: this.bindMatrixInverseNode,
88-
boneMatrices: this.boneMatricesNode
89-
}, stack, builder ) ).build( builder );*/
90-
Skinning.call( {
91-
index: this.skinIndexNode,
92-
weight: this.skinWeightNode,
93-
bindMatrix: this.bindMatrixNode,
94-
bindMatrixInverse: this.bindMatrixInverseNode,
95-
boneMatrices: this.boneMatricesNode
96-
}, {}, builder );
77+
}
9778

9879
}
9980

examples/jsm/nodes/code/CodeNode.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ class CodeNode extends Node {
7070
export default CodeNode;
7171

7272
export const code = nodeProxy( CodeNode );
73+
7374
export const js = ( src, includes ) => code( src, includes, 'js' );
75+
export const wgsl = ( src, includes ) => code( src, includes, 'wgsl' );
76+
export const glsl = ( src, includes ) => code( src, includes, 'glsl' );
7477

7578
addNodeClass( CodeNode );

examples/jsm/nodes/code/FunctionNode.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { nodeObject } from '../shadernode/ShaderNode.js';
44

55
class FunctionNode extends CodeNode {
66

7-
constructor( code = '', includes = [] ) {
7+
constructor( code = '', includes = [], language = '' ) {
88

9-
super( code, includes );
9+
super( code, includes, language );
1010

1111
this.keywords = {};
1212

@@ -99,8 +99,29 @@ class FunctionNode extends CodeNode {
9999

100100
export default FunctionNode;
101101

102-
export const func = ( code, includes ) => nodeObject( new FunctionNode( code, includes ) );
102+
const nativeFn = ( code, includes, language = '' ) => {
103103

104-
export const fn = ( code, includes ) => func( code, includes ).call;
104+
let functionNode = null;
105+
106+
return ( ...params ) => {
107+
108+
if ( functionNode === null ) functionNode = nodeObject( new FunctionNode( code, includes, language ) );
109+
110+
return functionNode.call( ...params );
111+
112+
};
113+
114+
};
115+
116+
export const glslFn = ( code, includes ) => nativeFn( code, includes, 'glsl' );
117+
export const wgslFn = ( code, includes ) => nativeFn( code, includes, 'wgsl' );
118+
119+
export const func = ( code, includes ) => { // @deprecated, r154
120+
121+
console.warn( 'TSL: func() is deprecated. Use nativeFn(), wgslFn() or glslFn() instead.' );
122+
123+
return nodeObject( new FunctionNode( code, includes ) );
124+
125+
};
105126

106127
addNodeClass( FunctionNode );

examples/jsm/nodes/core/BypassNode.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class BypassNode extends Node {
2020

2121
}
2222

23-
generate( builder, output ) {
23+
generate( builder ) {
2424

2525
const snippet = this.callNode.build( builder, 'void' );
2626

@@ -30,7 +30,7 @@ class BypassNode extends Node {
3030

3131
}
3232

33-
return this.outputNode.build( builder, output );
33+
return this.outputNode.build( builder );
3434

3535
}
3636

examples/jsm/nodes/core/Node.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,17 @@ class Node {
195195

196196
if ( properties.initialized !== true || builder.context.tempRead === false ) {
197197

198+
const stackNodesBeforeConstruct = builder.stack.nodes.length;
199+
198200
properties.initialized = true;
199201
properties.outputNode = this.construct( builder );
200202

203+
if ( properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeConstruct ) {
204+
205+
properties.outputNode = builder.stack;
206+
207+
}
208+
201209
for ( const childNode of Object.values( properties ) ) {
202210

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

examples/jsm/nodes/core/StackNode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class StackNode extends Node {
8282

8383
for ( const node of this.nodes ) {
8484

85-
node.build( builder );
85+
node.build( builder, 'void' );
8686

8787
}
8888

examples/jsm/nodes/display/BlendModeNode.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
11
import TempNode from '../core/TempNode.js';
22
import { EPSILON } from '../math/MathNode.js';
33
import { addNodeClass } from '../core/Node.js';
4-
import { addNodeElement, ShaderNode, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
4+
import { addNodeElement, tslFn, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
55

6-
export const BurnNode = new ShaderNode( ( { base, blend } ) => {
6+
export const BurnNode = tslFn( ( { base, blend } ) => {
77

88
const fn = ( c ) => blend[ c ].lessThan( EPSILON ).cond( blend[ c ], base[ c ].oneMinus().div( blend[ c ] ).oneMinus().max( 0 ) );
99

1010
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
1111

1212
} );
1313

14-
export const DodgeNode = new ShaderNode( ( { base, blend } ) => {
14+
export const DodgeNode = tslFn( ( { base, blend } ) => {
1515

1616
const fn = ( c ) => blend[ c ].equal( 1.0 ).cond( blend[ c ], base[ c ].div( blend[ c ].oneMinus() ).max( 0 ) );
1717

1818
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
1919

2020
} );
2121

22-
export const ScreenNode = new ShaderNode( ( { base, blend } ) => {
22+
export const ScreenNode = tslFn( ( { base, blend } ) => {
2323

2424
const fn = ( c ) => base[ c ].oneMinus().mul( blend[ c ].oneMinus() ).oneMinus();
2525

2626
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
2727

2828
} );
2929

30-
export const OverlayNode = new ShaderNode( ( { base, blend } ) => {
30+
export const OverlayNode = tslFn( ( { base, blend } ) => {
3131

3232
const fn = ( c ) => base[ c ].lessThan( 0.5 ).cond( base[ c ].mul( blend[ c ], 2.0 ), base[ c ].oneMinus().mul( blend[ c ].oneMinus() ).oneMinus() );
3333

@@ -57,19 +57,19 @@ class BlendModeNode extends TempNode {
5757

5858
if ( blendMode === BlendModeNode.BURN ) {
5959

60-
outputNode = BurnNode.call( params );
60+
outputNode = BurnNode( params );
6161

6262
} else if ( blendMode === BlendModeNode.DODGE ) {
6363

64-
outputNode = DodgeNode.call( params );
64+
outputNode = DodgeNode( params );
6565

6666
} else if ( blendMode === BlendModeNode.SCREEN ) {
6767

68-
outputNode = ScreenNode.call( params );
68+
outputNode = ScreenNode( params );
6969

7070
} else if ( blendMode === BlendModeNode.OVERLAY ) {
7171

72-
outputNode = OverlayNode.call( params );
72+
outputNode = OverlayNode( params );
7373

7474
}
7575

examples/jsm/nodes/display/ColorAdjustmentNode.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import TempNode from '../core/TempNode.js';
22
import { dot, mix } from '../math/MathNode.js';
33
import { add } from '../math/OperatorNode.js';
44
import { addNodeClass } from '../core/Node.js';
5-
import { addNodeElement, ShaderNode, nodeProxy, float, vec3, mat3 } from '../shadernode/ShaderNode.js';
5+
import { addNodeElement, tslFn, nodeProxy, float, vec3, mat3 } from '../shadernode/ShaderNode.js';
66

7-
const saturationNode = new ShaderNode( ( { color, adjustment } ) => {
7+
const saturationNode = tslFn( ( { color, adjustment } ) => {
88

99
return adjustment.mix( luminance( color ), color );
1010

1111
} );
1212

13-
const vibranceNode = new ShaderNode( ( { color, adjustment } ) => {
13+
const vibranceNode = tslFn( ( { color, adjustment } ) => {
1414

1515
const average = add( color.r, color.g, color.b ).div( 3.0 );
1616

@@ -21,7 +21,7 @@ const vibranceNode = new ShaderNode( ( { color, adjustment } ) => {
2121

2222
} );
2323

24-
const hueNode = new ShaderNode( ( { color, adjustment } ) => {
24+
const hueNode = tslFn( ( { color, adjustment } ) => {
2525

2626
const RGBtoYIQ = mat3( 0.299, 0.587, 0.114, 0.595716, - 0.274453, - 0.321263, 0.211456, - 0.522591, 0.311135 );
2727
const YIQtoRGB = mat3( 1.0, 0.9563, 0.6210, 1.0, - 0.2721, - 0.6474, 1.0, - 1.107, 1.7046 );
@@ -58,15 +58,15 @@ class ColorAdjustmentNode extends TempNode {
5858

5959
if ( method === ColorAdjustmentNode.SATURATION ) {
6060

61-
outputNode = saturationNode.call( callParams );
61+
outputNode = saturationNode( callParams );
6262

6363
} else if ( method === ColorAdjustmentNode.VIBRANCE ) {
6464

65-
outputNode = vibranceNode.call( callParams );
65+
outputNode = vibranceNode( callParams );
6666

6767
} else if ( method === ColorAdjustmentNode.HUE ) {
6868

69-
outputNode = hueNode.call( callParams );
69+
outputNode = hueNode( callParams );
7070

7171
} else {
7272

0 commit comments

Comments
 (0)