@@ -16,8 +16,10 @@ function shadergenerator(p5, fn) {
1616
1717 const oldModify = p5 . Shader . prototype . modify
1818
19- p5 . Shader . prototype . modify = function ( shaderModifier , options = { parser : true , srcLocations : false } ) {
19+ p5 . Shader . prototype . modify = function ( shaderModifier , scope = { } ) {
2020 if ( shaderModifier instanceof Function ) {
21+ // TODO make this public. Currently for debugging only.
22+ const options = { parser : true , srcLocations : false } ;
2123 let generatorFunction ;
2224 if ( options . parser ) {
2325 const sourceString = shaderModifier . toString ( )
@@ -27,13 +29,17 @@ function shadergenerator(p5, fn) {
2729 } ) ;
2830 ancestor ( ast , ASTCallbacks , undefined , { varyings : { } } ) ;
2931 const transpiledSource = escodegen . generate ( ast ) ;
30- generatorFunction = new Function (
32+ const scopeKeys = Object . keys ( scope ) ;
33+ const internalGeneratorFunction = new Function (
34+ 'p5' ,
35+ ...scopeKeys ,
3136 transpiledSource
3237 . slice (
3338 transpiledSource . indexOf ( '{' ) + 1 ,
3439 transpiledSource . lastIndexOf ( '}' )
3540 ) . replaceAll ( ';' , '' )
3641 ) ;
42+ generatorFunction = ( ) => internalGeneratorFunction ( p5 , ...scopeKeys . map ( key => scope [ key ] ) ) ;
3743 } else {
3844 generatorFunction = shaderModifier ;
3945 }
@@ -64,15 +70,24 @@ function shadergenerator(p5, fn) {
6470 }
6571 }
6672
67- function ancestorIsUniform ( ancestor ) {
73+ function nodeIsUniform ( ancestor ) {
6874 return ancestor . type === 'CallExpression'
69- && ancestor . callee ?. type === 'Identifier'
70- && ancestor . callee ?. name . startsWith ( 'uniform' ) ;
75+ && (
76+ (
77+ // Global mode
78+ ancestor . callee ?. type === 'Identifier' &&
79+ ancestor . callee ?. name . startsWith ( 'uniform' )
80+ ) || (
81+ // Instance mode
82+ ancestor . callee ?. type === 'MemberExpression' &&
83+ ancestor . callee ?. property . name . startsWith ( 'uniform' )
84+ )
85+ ) ;
7186 }
7287
7388 const ASTCallbacks = {
74- UnaryExpression ( node , _state , _ancestors ) {
75- if ( _ancestors . some ( ancestorIsUniform ) ) { return ; }
89+ UnaryExpression ( node , _state , ancestors ) {
90+ if ( ancestors . some ( nodeIsUniform ) ) { return ; }
7691
7792 const signNode = {
7893 type : 'Literal' ,
@@ -83,7 +98,7 @@ function shadergenerator(p5, fn) {
8398 node . type = 'CallExpression'
8499 node . callee = {
85100 type : 'Identifier' ,
86- name : 'unaryNode' ,
101+ name : 'p5. unaryNode' ,
87102 }
88103 node . arguments = [ node . argument , signNode ]
89104 }
@@ -106,7 +121,7 @@ function shadergenerator(p5, fn) {
106121 type : 'CallExpression' ,
107122 callee : {
108123 type : 'Identifier' ,
109- name : 'unaryNode'
124+ name : 'p5. unaryNode'
110125 } ,
111126 arguments : [ node . argument . object , signNode ] ,
112127 } ;
@@ -123,8 +138,9 @@ function shadergenerator(p5, fn) {
123138 delete node . argument ;
124139 delete node . operator ;
125140 } ,
126- VariableDeclarator ( node , _state , _ancestors ) {
127- if ( node . init . callee && node . init . callee . name ?. startsWith ( 'uniform' ) ) {
141+ VariableDeclarator ( node , _state , ancestors ) {
142+ if ( ancestors . some ( nodeIsUniform ) ) { return ; }
143+ if ( nodeIsUniform ( node . init ) ) {
128144 const uniformNameLiteral = {
129145 type : 'Literal' ,
130146 value : node . id . name
@@ -140,7 +156,8 @@ function shadergenerator(p5, fn) {
140156 _state . varyings [ node . id . name ] = varyingNameLiteral ;
141157 }
142158 } ,
143- Identifier ( node , _state , _ancestors ) {
159+ Identifier ( node , _state , ancestors ) {
160+ if ( ancestors . some ( nodeIsUniform ) ) { return ; }
144161 if ( _state . varyings [ node . name ]
145162 && ! _ancestors . some ( a => a . type === 'AssignmentExpression' && a . left === node ) ) {
146163 node . type = 'ExpressionStatement' ;
@@ -163,16 +180,18 @@ function shadergenerator(p5, fn) {
163180 } ,
164181 // The callbacks for AssignmentExpression and BinaryExpression handle
165182 // operator overloading including +=, *= assignment expressions
166- ArrayExpression ( node , _state , _ancestors ) {
183+ ArrayExpression ( node , _state , ancestors ) {
184+ if ( ancestors . some ( nodeIsUniform ) ) { return ; }
167185 const original = JSON . parse ( JSON . stringify ( node ) ) ;
168186 node . type = 'CallExpression' ;
169187 node . callee = {
170188 type : 'Identifier' ,
171- name : 'dynamicNode' ,
189+ name : 'p5. dynamicNode' ,
172190 } ;
173191 node . arguments = [ original ] ;
174192 } ,
175- AssignmentExpression ( node , _state , _ancestors ) {
193+ AssignmentExpression ( node , _state , ancestors ) {
194+ if ( ancestors . some ( nodeIsUniform ) ) { return ; }
176195 if ( node . operator !== '=' ) {
177196 const methodName = replaceBinaryOperator ( node . operator . replace ( '=' , '' ) ) ;
178197 const rightReplacementNode = {
@@ -209,10 +228,10 @@ function shadergenerator(p5, fn) {
209228 }
210229 }
211230 } ,
212- BinaryExpression ( node , _state , _ancestors ) {
231+ BinaryExpression ( node , _state , ancestors ) {
213232 // Don't convert uniform default values to node methods, as
214233 // they should be evaluated at runtime, not compiled.
215- if ( _ancestors . some ( ancestorIsUniform ) ) { return ; }
234+ if ( ancestors . some ( nodeIsUniform ) ) { return ; }
216235 // If the left hand side of an expression is one of these types,
217236 // we should construct a node from it.
218237 const unsafeTypes = [ 'Literal' , 'ArrayExpression' , 'Identifier' ] ;
@@ -221,7 +240,7 @@ function shadergenerator(p5, fn) {
221240 type : 'CallExpression' ,
222241 callee : {
223242 type : 'Identifier' ,
224- name : 'dynamicNode' ,
243+ name : 'p5. dynamicNode' ,
225244 } ,
226245 arguments : [ node . left ]
227246 }
@@ -1010,7 +1029,7 @@ function shadergenerator(p5, fn) {
10101029 return length
10111030 }
10121031
1013- fn . dynamicNode = function ( input ) {
1032+ p5 . dynamicNode = function ( input ) {
10141033 if ( isShaderNode ( input ) ) {
10151034 return input ;
10161035 }
@@ -1023,8 +1042,8 @@ function shadergenerator(p5, fn) {
10231042 }
10241043
10251044 // For replacing unary expressions
1026- fn . unaryNode = function ( input , sign ) {
1027- input = dynamicNode ( input ) ;
1045+ p5 . unaryNode = function ( input , sign ) {
1046+ input = p5 . dynamicNode ( input ) ;
10281047 return dynamicAddSwizzleTrap ( new UnaryExpressionNode ( input , sign ) ) ;
10291048 }
10301049
@@ -1131,6 +1150,7 @@ function shadergenerator(p5, fn) {
11311150 }
11321151
11331152 const windowOverrides = { } ;
1153+ const fnOverrides = { } ;
11341154
11351155 Object . keys ( availableHooks ) . forEach ( ( hookName ) => {
11361156 const hookTypes = originalShader . hookTypes ( hookName ) ;
@@ -1166,7 +1186,7 @@ function shadergenerator(p5, fn) {
11661186 // If the expected return type is a struct we need to evaluate each of its properties
11671187 if ( ! isGLSLNativeType ( expectedReturnType . typeName ) ) {
11681188 Object . entries ( returnedValue ) . forEach ( ( [ propertyName , propertyNode ] ) => {
1169- propertyNode = dynamicNode ( propertyNode ) ;
1189+ propertyNode = p5 . dynamicNode ( propertyNode ) ;
11701190 toGLSLResults [ propertyName ] = propertyNode . toGLSLBase ( this . context ) ;
11711191 this . context . updateComponents ( propertyNode ) ;
11721192 } ) ;
@@ -1216,18 +1236,25 @@ function shadergenerator(p5, fn) {
12161236 this . resetGLSLContext ( ) ;
12171237 }
12181238 windowOverrides [ hookTypes . name ] = window [ hookTypes . name ] ;
1239+ fnOverrides [ hookTypes . name ] = fn [ hookTypes . name ] ;
12191240
12201241 // Expose the Functions to global scope for users to use
12211242 window [ hookTypes . name ] = function ( userOverride ) {
12221243 GLOBAL_SHADER [ hookTypes . name ] ( userOverride ) ;
12231244 } ;
1245+ fn [ hookTypes . name ] = function ( userOverride ) {
1246+ GLOBAL_SHADER [ hookTypes . name ] ( userOverride ) ;
1247+ } ;
12241248 } ) ;
12251249
12261250
12271251 this . cleanup = ( ) => {
12281252 for ( const key in windowOverrides ) {
12291253 window [ key ] = windowOverrides [ key ] ;
12301254 }
1255+ for ( const key in fnOverrides ) {
1256+ fn [ key ] = fnOverrides [ key ] ;
1257+ }
12311258 } ;
12321259 }
12331260
@@ -1636,14 +1663,14 @@ function shadergenerator(p5, fn) {
16361663 if ( ! GLOBAL_SHADER ?. isGenerating ) {
16371664 return originalNoise . apply ( this , args ) ; // fallback to regular p5.js noise
16381665 }
1639-
1666+
16401667 GLOBAL_SHADER . output . vertexDeclarations . add ( noiseGLSL ) ;
16411668 GLOBAL_SHADER . output . fragmentDeclarations . add ( noiseGLSL ) ;
16421669 return fnNodeConstructor ( 'noise' , args , { args : [ 'vec2' ] , returnType : 'float' } ) ;
16431670 } ;
16441671}
1645-
1646-
1672+
1673+
16471674export default shadergenerator ;
16481675
16491676if ( typeof p5 !== 'undefined' ) {
0 commit comments