11import * as TSL from 'three/tsl' ;
22import * as THREE from 'three/webgpu' ;
33
4+
5+ export type UniformType = "boolean" | "number" | "Color" | "Vector2" | "Vector3" | "Vector4" | "Matrix3" | "Matrix4" ;
6+
47/**
58 * Handles the creation of the TSL output string
69 */
@@ -10,6 +13,12 @@ export class Script {
1013
1114 protected imports :Record < string , Set < string > > ;
1215 protected definitions :[ name :string , value :string ] [ ] ;
16+
17+ /**
18+ * array of [ index the definition in the definitions array, the variable type of the uniform ]
19+ */
20+ protected uniforms :[ name :string , type :UniformType , initialValue :string ] [ ] = [ ] ;
21+
1322 protected imagePaths :[ path :string , previewImage ?:string , textureSetup ?:( refName :string ) => string ] [ ] ;
1423 protected moduleName2Ref :Record < string , unknown > ;
1524
@@ -39,6 +48,25 @@ export class Script {
3948 return varName ;
4049 }
4150
51+ /**
52+ * Defines a uniform variable.
53+ *
54+ *
55+ * @see https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language#uniform
56+ * @param varName
57+ * @param initialValue must ve a valid uniform value.
58+ * @returns the name of the variable holding the uniform.
59+ */
60+ defineUniform ( varName :string , type :UniformType , initialValue :string ) {
61+
62+ if ( ! this . uniforms . find ( u => u [ 0 ] == varName ) )
63+ {
64+ this . uniforms . push ( [ varName , type , initialValue ] ) ;
65+ }
66+
67+ return "$uniforms." + varName ;
68+ }
69+
4270 /**
4371 * Module to import
4472 * @param dep
@@ -92,10 +120,12 @@ export class Script {
92120
93121 toString ( lastExpression :string = "" , forExport = false ) {
94122
95- let output = `` ;
123+ let output = `\n ` ;
96124
97125 if ( forExport )
98126 {
127+ output += "import * as THREE from 'three/webgpu';\n" ;
128+
99129 //
100130 // Imports...
101131 //
@@ -113,6 +143,13 @@ export class Script {
113143 ` ;
114144 }
115145
146+ //
147+ // uniforms
148+ //
149+ output += "\n" + ( forExport ?"export" :"" ) + " const $uniforms = {\n" +
150+ this . uniforms . map ( uniform => `${ uniform [ 0 ] } : uniform( ${ uniform [ 2 ] } )` ) . join ( "," )
151+ + "\n}\n" ;
152+
116153 //
117154 // image loaders...
118155 //
@@ -157,4 +194,28 @@ export class Script {
157194
158195 return eval ( this . toString ( returnThisRef , false ) ) ;
159196 }
197+
198+ public static makeValidVariableName ( input :string ) {
199+ // Return empty string if input is not a string or is empty
200+ if ( typeof input !== 'string' || input . trim ( ) === '' ) {
201+ return 'foo' ;
202+ }
203+
204+ let str = input . trim ( ) ;
205+
206+ // Remove or replace invalid characters
207+ str = str . replace ( / [ ^ a - z A - Z 0 - 9 _ $ ] / g, '_' ) ;
208+
209+ // If starts with a number, prepend an underscore
210+ if ( / ^ \d / . test ( str ) ) {
211+ str = '_' + str ;
212+ }
213+
214+ // If empty after cleaning or starts with invalid character, use default name
215+ if ( ! str || ! / ^ [ a - z A - Z _ $ ] / . test ( str ) ) {
216+ return 'validVar' ;
217+ }
218+
219+ return "$" + str ;
220+ }
160221}
0 commit comments