| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- import Node from './Node.js';
- import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js';
- /** @module VarNode **/
- /**
- * Class for representing shader variables as nodes. Variables are created from
- * existing nodes like the following:
- *
- * ```js
- * const depth = sampleDepth( uvNode ).toVar( 'depth' );
- * ```
- *
- * @augments Node
- */
- class VarNode extends Node {
- static get type() {
- return 'VarNode';
- }
- /**
- * Constructs a new variable node.
- *
- * @param {Node} node - The node for which a variable should be created.
- * @param {String?} name - The name of the variable in the shader.
- * @param {Boolean?} readOnly - The read-only flag.
- */
- constructor( node, name = null, readOnly = false ) {
- super();
- /**
- * The node for which a variable should be created.
- *
- * @type {Node}
- */
- this.node = node;
- /**
- * The name of the variable in the shader. If no name is defined,
- * the node system auto-generates one.
- *
- * @type {String?}
- * @default null
- */
- this.name = name;
- /**
- * `VarNode` sets this property to `true` by default.
- *
- * @type {Boolean}
- * @default true
- */
- this.global = true;
- /**
- * This flag can be used for type testing.
- *
- * @type {Boolean}
- * @readonly
- * @default true
- */
- this.isVarNode = true;
- /**
- *
- * The read-only flag.
- *
- * @type {Boolean}
- * @default false
- */
- this.readOnly = readOnly;
- }
- getHash( builder ) {
- return this.name || super.getHash( builder );
- }
- getElementType( builder ) {
- return this.node.getElementType( builder );
- }
- getNodeType( builder ) {
- return this.node.getNodeType( builder );
- }
- generate( builder ) {
- const { node, name, readOnly } = this;
- const { renderer } = builder;
- const isWebGPUBackend = renderer.backend.isWebGPUBackend === true;
- let isDeterministic = false;
- let shouldTreatAsReadOnly = false;
- if ( readOnly ) {
- isDeterministic = builder.isDeterministic( node );
- shouldTreatAsReadOnly = isWebGPUBackend ? readOnly : isDeterministic;
- }
- const vectorType = builder.getVectorType( this.getNodeType( builder ) );
- const snippet = node.build( builder, vectorType );
- const nodeVar = builder.getVarFromNode( this, name, vectorType, undefined, shouldTreatAsReadOnly );
- const propertyName = builder.getPropertyName( nodeVar );
- let declarationPrefix = propertyName;
- if ( shouldTreatAsReadOnly ) {
- if ( isWebGPUBackend ) {
- declarationPrefix = isDeterministic
- ? `const ${ propertyName }`
- : `let ${ propertyName }`;
- } else {
- const count = builder.getArrayCount( node );
- declarationPrefix = `const ${ builder.getVar( nodeVar.type, propertyName, count ) }`;
- }
- }
- builder.addLineFlowCode( `${ declarationPrefix } = ${ snippet }`, this );
- return propertyName;
- }
- }
- export default VarNode;
- /**
- * TSL function for creating a var node.
- *
- * @function
- * @param {Node} node - The node for which a variable should be created.
- * @param {String?} name - The name of the variable in the shader.
- * @returns {VarNode}
- */
- const createVar = /*@__PURE__*/ nodeProxy( VarNode );
- /**
- * TSL function for creating a var node.
- *
- * @function
- * @param {Node} node - The node for which a variable should be created.
- * @param {String?} name - The name of the variable in the shader.
- * @returns {VarNode}
- */
- export const Var = ( node, name = null ) => createVar( node, name ).append();
- /**
- * TSL function for creating a const node.
- *
- * @function
- * @param {Node} node - The node for which a constant should be created.
- * @param {String?} name - The name of the constant in the shader.
- * @returns {VarNode}
- */
- export const Const = ( node, name = null ) => createVar( node, name, true ).append();
- // Method chaining
- addMethodChaining( 'toVar', Var );
- addMethodChaining( 'toConst', Const );
- // Deprecated
- /**
- * @function
- * @deprecated since r170. Use `Var( node )` or `node.toVar()` instead.
- *
- * @param {Any} node
- * @returns {VarNode}
- */
- export const temp = ( node ) => { // @deprecated, r170
- console.warn( 'TSL: "temp( node )" is deprecated. Use "Var( node )" or "node.toVar()" instead.' );
- return createVar( node );
- };
- addMethodChaining( 'temp', temp );
|