@@ -26,8 +26,9 @@ class VarNode extends Node {
2626 *
2727 * @param {Node } node - The node for which a variable should be created.
2828 * @param {String? } name - The name of the variable in the shader.
29+ * @param {Boolean? } readOnly - The read-only flag.
2930 */
30- constructor ( node , name = null ) {
31+ constructor ( node , name = null , readOnly = false ) {
3132
3233 super ( ) ;
3334
@@ -64,6 +65,15 @@ class VarNode extends Node {
6465 */
6566 this . isVarNode = true ;
6667
68+ /**
69+ *
70+ * The read-only flag.
71+ *
72+ * @type {Boolean }
73+ * @default false
74+ */
75+ this . readOnly = readOnly ;
76+
6777 }
6878
6979 getHash ( builder ) {
@@ -80,15 +90,50 @@ class VarNode extends Node {
8090
8191 generate ( builder ) {
8292
83- const { node, name } = this ;
93+ const { node, name, readOnly } = this ;
94+ const { renderer } = builder ;
95+
96+ const isWebGPUBackend = renderer . backend . isWebGPUBackend === true ;
97+
98+ let isDeterministic = false ;
99+ let shouldTreatAsReadOnly = false ;
100+
101+ if ( readOnly ) {
102+
103+ isDeterministic = builder . isDeterministic ( node ) ;
84104
85- const nodeVar = builder . getVarFromNode ( this , name , builder . getVectorType ( this . getNodeType ( builder ) ) ) ;
105+ shouldTreatAsReadOnly = isWebGPUBackend ? readOnly : isDeterministic ;
106+
107+ }
108+
109+ const vectorType = builder . getVectorType ( this . getNodeType ( builder ) ) ;
110+ const snippet = node . build ( builder , vectorType ) ;
111+
112+ const nodeVar = builder . getVarFromNode ( this , name , vectorType , undefined , shouldTreatAsReadOnly ) ;
86113
87114 const propertyName = builder . getPropertyName ( nodeVar ) ;
88115
89- const snippet = node . build ( builder , nodeVar . type ) ;
116+ let declarationPrefix = propertyName ;
117+
118+ if ( shouldTreatAsReadOnly ) {
119+
120+ const type = builder . getType ( nodeVar . type ) ;
121+
122+ if ( isWebGPUBackend ) {
123+
124+ declarationPrefix = isDeterministic
125+ ? `const ${ propertyName } `
126+ : `let ${ propertyName } ` ;
127+
128+ } else {
129+
130+ declarationPrefix = `const ${ type } ${ propertyName } ` ;
90131
91- builder . addLineFlowCode ( `${ propertyName } = ${ snippet } ` , this ) ;
132+ }
133+
134+ }
135+
136+ builder . addLineFlowCode ( `${ declarationPrefix } = ${ snippet } ` , this ) ;
92137
93138 return propertyName ;
94139
@@ -108,13 +153,36 @@ export default VarNode;
108153 */
109154const createVar = /*@__PURE__ */ nodeProxy ( VarNode ) ;
110155
111- addMethodChaining ( 'toVar' , ( ...params ) => createVar ( ...params ) . append ( ) ) ;
156+ /**
157+ * TSL function for creating a var node.
158+ *
159+ * @function
160+ * @param {Node } node - The node for which a variable should be created.
161+ * @param {String? } name - The name of the variable in the shader.
162+ * @returns {VarNode }
163+ */
164+ export const Var = ( node , name = null ) => createVar ( node , name ) . append ( ) ;
165+
166+ /**
167+ * TSL function for creating a const node.
168+ *
169+ * @function
170+ * @param {Node } node - The node for which a constant should be created.
171+ * @param {String? } name - The name of the constant in the shader.
172+ * @returns {VarNode }
173+ */
174+ export const Const = ( node , name = null ) => createVar ( node , name , true ) . append ( ) ;
175+
176+ // Method chaining
177+
178+ addMethodChaining ( 'toVar' , Var ) ;
179+ addMethodChaining ( 'toConst' , Const ) ;
112180
113181// Deprecated
114182
115183export const temp = ( node ) => { // @deprecated , r170
116184
117- console . warn ( 'TSL: "temp" is deprecated. Use ".toVar()" instead.' ) ;
185+ console . warn ( 'TSL: "temp( node ) " is deprecated. Use "Var( node )" or "node .toVar()" instead.' ) ;
118186
119187 return createVar ( node ) ;
120188
0 commit comments