|
|
@@ -251,15 +251,7 @@ class ShaderCallNodeInternal extends Node {
|
|
|
|
|
|
getNodeType( builder ) {
|
|
|
|
|
|
- const properties = builder.getNodeProperties( this );
|
|
|
-
|
|
|
- if ( properties.outputNode === null ) {
|
|
|
-
|
|
|
- properties.outputNode = this.setupOutput( builder );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return properties.outputNode.getNodeType( builder );
|
|
|
+ return this.shaderNode.nodeType || this.getOutputNode( builder ).getNodeType( builder );
|
|
|
|
|
|
}
|
|
|
|
|
|
@@ -267,6 +259,13 @@ class ShaderCallNodeInternal extends Node {
|
|
|
|
|
|
const { shaderNode, inputNodes } = this;
|
|
|
|
|
|
+ const properties = builder.getNodeProperties( shaderNode );
|
|
|
+ if ( properties.onceOutput ) return properties.onceOutput;
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ let result = null;
|
|
|
+
|
|
|
if ( shaderNode.layout ) {
|
|
|
|
|
|
let functionNodesCacheMap = nodeBuilderFunctionsCacheMap.get( builder.constructor );
|
|
|
@@ -295,22 +294,44 @@ class ShaderCallNodeInternal extends Node {
|
|
|
|
|
|
}
|
|
|
|
|
|
- return nodeObject( functionNode.call( inputNodes ) );
|
|
|
+ result = nodeObject( functionNode.call( inputNodes ) );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ const jsFunc = shaderNode.jsFunc;
|
|
|
+ const outputNode = inputNodes !== null ? jsFunc( inputNodes, builder ) : jsFunc( builder );
|
|
|
+
|
|
|
+ result = nodeObject( outputNode );
|
|
|
|
|
|
}
|
|
|
|
|
|
- const jsFunc = shaderNode.jsFunc;
|
|
|
- const outputNode = inputNodes !== null ? jsFunc( inputNodes, builder ) : jsFunc( builder );
|
|
|
+ if ( shaderNode.once ) {
|
|
|
+
|
|
|
+ properties.onceOutput = result;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- return nodeObject( outputNode );
|
|
|
+ return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
- setup( builder ) {
|
|
|
+ getOutputNode( builder ) {
|
|
|
|
|
|
- const { outputNode } = builder.getNodeProperties( this );
|
|
|
+ const properties = builder.getNodeProperties( this );
|
|
|
|
|
|
- return outputNode || this.setupOutput( builder );
|
|
|
+ if ( properties.outputNode === null ) {
|
|
|
+
|
|
|
+ properties.outputNode = this.setupOutput( builder );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return properties.outputNode;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ setup( builder ) {
|
|
|
+
|
|
|
+ return this.getOutputNode( builder );
|
|
|
|
|
|
}
|
|
|
|
|
|
@@ -326,17 +347,9 @@ class ShaderCallNodeInternal extends Node {
|
|
|
|
|
|
generate( builder, output ) {
|
|
|
|
|
|
- const { outputNode } = builder.getNodeProperties( this );
|
|
|
-
|
|
|
- if ( outputNode === null ) {
|
|
|
-
|
|
|
- // TSL: It's recommended to use `tslFn` in setup() pass.
|
|
|
-
|
|
|
- return this.call( builder ).build( builder, output );
|
|
|
+ const outputNode = this.getOutputNode( builder );
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- return super.generate( builder, output );
|
|
|
+ return outputNode.build( builder, output );
|
|
|
|
|
|
}
|
|
|
|
|
|
@@ -344,15 +357,17 @@ class ShaderCallNodeInternal extends Node {
|
|
|
|
|
|
class ShaderNodeInternal extends Node {
|
|
|
|
|
|
- constructor( jsFunc ) {
|
|
|
+ constructor( jsFunc, nodeType ) {
|
|
|
|
|
|
- super();
|
|
|
+ super( nodeType );
|
|
|
|
|
|
this.jsFunc = jsFunc;
|
|
|
this.layout = null;
|
|
|
|
|
|
this.global = true;
|
|
|
|
|
|
+ this.once = false;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
get isArrayInput() {
|
|
|
@@ -480,9 +495,9 @@ export const getConstNodeType = ( value ) => ( value !== undefined && value !==
|
|
|
|
|
|
// shader node base
|
|
|
|
|
|
-export function ShaderNode( jsFunc ) {
|
|
|
+export function ShaderNode( jsFunc, nodeType ) {
|
|
|
|
|
|
- return new Proxy( new ShaderNodeInternal( jsFunc ), shaderNodeHandler );
|
|
|
+ return new Proxy( new ShaderNodeInternal( jsFunc, nodeType ), shaderNodeHandler );
|
|
|
|
|
|
}
|
|
|
|
|
|
@@ -492,9 +507,9 @@ export const nodeArray = ( val, altType = null ) => new ShaderNodeArray( val, al
|
|
|
export const nodeProxy = ( ...params ) => new ShaderNodeProxy( ...params );
|
|
|
export const nodeImmutable = ( ...params ) => new ShaderNodeImmutable( ...params );
|
|
|
|
|
|
-export const Fn = ( jsFunc ) => {
|
|
|
+export const Fn = ( jsFunc, nodeType ) => {
|
|
|
|
|
|
- const shaderNode = new ShaderNode( jsFunc );
|
|
|
+ const shaderNode = new ShaderNode( jsFunc, nodeType );
|
|
|
|
|
|
const fn = ( ...params ) => {
|
|
|
|
|
|
@@ -517,6 +532,7 @@ export const Fn = ( jsFunc ) => {
|
|
|
};
|
|
|
|
|
|
fn.shaderNode = shaderNode;
|
|
|
+
|
|
|
fn.setLayout = ( layout ) => {
|
|
|
|
|
|
shaderNode.setLayout( layout );
|
|
|
@@ -525,13 +541,21 @@ export const Fn = ( jsFunc ) => {
|
|
|
|
|
|
};
|
|
|
|
|
|
+ fn.once = () => {
|
|
|
+
|
|
|
+ shaderNode.once = true;
|
|
|
+
|
|
|
+ return fn;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
return fn;
|
|
|
|
|
|
};
|
|
|
|
|
|
export const tslFn = ( ...params ) => { // @deprecated, r168
|
|
|
|
|
|
- console.warn( 'TSL.tslFn: tslFn() has been renamed to Fn().' );
|
|
|
+ console.warn( 'TSL.ShaderNode: tslFn() has been renamed to Fn().' );
|
|
|
return Fn( ...params );
|
|
|
|
|
|
};
|