The standard way to do this in TSL isn’t to “return early” like you describe, but rather to conditionally assign a local variable, and then return that variable. You can turn a node into an “assignable” local variable in the shader by calling node.toVar()
:
const colorNode = Fn(() => {
const returnVal = vec3().toVar();
If(active.not(), () => {
returnVal.assign(texture(texture, uv()));
}).Else(() => {
// I'm assuming "finalColor" comes
// from some other scope
returnVal.assign(finalColor);
});
return returnVal;
});
You can see this pattern repeated all over in the three.js library.
For example, in ParallaxBarrierPassNode
(check out the parallaxBarrier
node):
class ParallaxBarrierPassNode extends StereoCompositePassNode {
static get type() {
return 'ParallaxBarrierPassNode';
}
constructor(scene, camera) {
super(scene, camera);
this.isParallaxBarrierPassNode = true;
}
setup(builder) {
const uvNode = uv();
const parallaxBarrier = Fn(() => {
const color = vec4().toVar();
If(mod(screenCoordinate.y, 2).greaterThan(1), () => {
color.assign(this._mapLeft.uv(uvNode));
}).Else(() => {
color.assign(this._mapRight.uv(uvNode));
});
return color;
});
const material = this._material || (this._material = new NodeMaterial());
material.fragmentNode = parallaxBarrier().context(builder.getSharedContext());
material.needsUpdate = true;
return super.setup(builder);
}
}