@@ -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        // #7955 Wrap function declaration code in brackets so anonymous functions are not top level statements, which causes an error in acorn when parsing 
@@ -29,13 +31,17 @@ function shadergenerator(p5, fn) {
2931        } ) ; 
3032        ancestor ( ast ,  ASTCallbacks ,  undefined ,  {  varyings : { }  } ) ; 
3133        const  transpiledSource  =  escodegen . generate ( ast ) ; 
32-         generatorFunction  =  new  Function ( 
34+         const  scopeKeys  =  Object . keys ( scope ) ; 
35+         const  internalGeneratorFunction  =  new  Function ( 
36+           'p5' , 
37+           ...scopeKeys , 
3338          transpiledSource 
3439          . slice ( 
3540            transpiledSource . indexOf ( '{' )  +  1 , 
3641            transpiledSource . lastIndexOf ( '}' ) 
3742          ) . replaceAll ( ';' ,  '' ) 
3843        ) ; 
44+         generatorFunction  =  ( )  =>  internalGeneratorFunction ( p5 ,  ...scopeKeys . map ( key  =>  scope [ key ] ) ) ; 
3945      }  else  { 
4046        generatorFunction  =  shaderModifier ; 
4147      } 
@@ -66,15 +72,24 @@ function shadergenerator(p5, fn) {
6672    } 
6773  } 
6874
69-   function  ancestorIsUniform ( ancestor )  { 
75+   function  nodeIsUniform ( ancestor )  { 
7076    return  ancestor . type  ===  'CallExpression' 
71-       &&  ancestor . callee ?. type  ===  'Identifier' 
72-       &&  ancestor . callee ?. name . startsWith ( 'uniform' ) ; 
77+       &&  ( 
78+         ( 
79+           // Global mode 
80+           ancestor . callee ?. type  ===  'Identifier'  && 
81+           ancestor . callee ?. name . startsWith ( 'uniform' ) 
82+         )  ||  ( 
83+           // Instance mode 
84+           ancestor . callee ?. type  ===  'MemberExpression'  && 
85+           ancestor . callee ?. property . name . startsWith ( 'uniform' ) 
86+         ) 
87+       ) ; 
7388  } 
7489
7590  const  ASTCallbacks  =  { 
76-     UnaryExpression ( node ,  _state ,  _ancestors )  { 
77-       if  ( _ancestors . some ( ancestorIsUniform ) )  {  return ;  } 
91+     UnaryExpression ( node ,  _state ,  ancestors )  { 
92+       if  ( ancestors . some ( nodeIsUniform ) )  {  return ;  } 
7893
7994      const  signNode  =  { 
8095        type : 'Literal' , 
@@ -85,7 +100,7 @@ function shadergenerator(p5, fn) {
85100          node . type  =  'CallExpression' 
86101          node . callee  =  { 
87102            type : 'Identifier' , 
88-             name : 'unaryNode' , 
103+             name : 'p5. unaryNode' , 
89104          } 
90105          node . arguments  =  [ node . argument ,  signNode ] 
91106      } 
@@ -108,7 +123,7 @@ function shadergenerator(p5, fn) {
108123            type : 'CallExpression' , 
109124            callee : { 
110125              type : 'Identifier' , 
111-               name : 'unaryNode' 
126+               name : 'p5. unaryNode' 
112127            } , 
113128            arguments : [ node . argument . object ,  signNode ] , 
114129          } ; 
@@ -125,8 +140,9 @@ function shadergenerator(p5, fn) {
125140      delete  node . argument ; 
126141      delete  node . operator ; 
127142    } , 
128-     VariableDeclarator ( node ,  _state ,  _ancestors )  { 
129-       if  ( node . init . callee  &&  node . init . callee . name ?. startsWith ( 'uniform' ) )  { 
143+     VariableDeclarator ( node ,  _state ,  ancestors )  { 
144+       if  ( ancestors . some ( nodeIsUniform ) )  {  return ;  } 
145+       if  ( nodeIsUniform ( node . init ) )  { 
130146        const  uniformNameLiteral  =  { 
131147          type : 'Literal' , 
132148          value : node . id . name 
@@ -142,7 +158,8 @@ function shadergenerator(p5, fn) {
142158        _state . varyings [ node . id . name ]  =  varyingNameLiteral ; 
143159      } 
144160    } , 
145-     Identifier ( node ,  _state ,  _ancestors )  { 
161+     Identifier ( node ,  _state ,  ancestors )  { 
162+       if  ( ancestors . some ( nodeIsUniform ) )  {  return ;  } 
146163      if  ( _state . varyings [ node . name ] 
147164          &&  ! _ancestors . some ( a  =>  a . type  ===  'AssignmentExpression'  &&  a . left  ===  node ) )  { 
148165        node . type  =  'ExpressionStatement' ; 
@@ -165,16 +182,18 @@ function shadergenerator(p5, fn) {
165182    } , 
166183    // The callbacks for AssignmentExpression and BinaryExpression handle 
167184    // operator overloading including +=, *= assignment expressions 
168-     ArrayExpression ( node ,  _state ,  _ancestors )  { 
185+     ArrayExpression ( node ,  _state ,  ancestors )  { 
186+       if  ( ancestors . some ( nodeIsUniform ) )  {  return ;  } 
169187      const  original  =  JSON . parse ( JSON . stringify ( node ) ) ; 
170188      node . type  =  'CallExpression' ; 
171189      node . callee  =  { 
172190        type : 'Identifier' , 
173-         name : 'dynamicNode' , 
191+         name : 'p5. dynamicNode' , 
174192      } ; 
175193      node . arguments  =  [ original ] ; 
176194    } , 
177-     AssignmentExpression ( node ,  _state ,  _ancestors )  { 
195+     AssignmentExpression ( node ,  _state ,  ancestors )  { 
196+       if  ( ancestors . some ( nodeIsUniform ) )  {  return ;  } 
178197      if  ( node . operator  !==  '=' )  { 
179198        const  methodName  =  replaceBinaryOperator ( node . operator . replace ( '=' , '' ) ) ; 
180199        const  rightReplacementNode  =  { 
@@ -211,10 +230,10 @@ function shadergenerator(p5, fn) {
211230          } 
212231        } 
213232      } , 
214-     BinaryExpression ( node ,  _state ,  _ancestors )  { 
233+     BinaryExpression ( node ,  _state ,  ancestors )  { 
215234      // Don't convert uniform default values to node methods, as 
216235      // they should be evaluated at runtime, not compiled. 
217-       if  ( _ancestors . some ( ancestorIsUniform ) )  {  return ;  } 
236+       if  ( ancestors . some ( nodeIsUniform ) )  {  return ;  } 
218237      // If the left hand side of an expression is one of these types, 
219238      // we should construct a node from it. 
220239      const  unsafeTypes  =  [ 'Literal' ,  'ArrayExpression' ,  'Identifier' ] ; 
@@ -223,7 +242,7 @@ function shadergenerator(p5, fn) {
223242          type : 'CallExpression' , 
224243          callee : { 
225244            type : 'Identifier' , 
226-             name : 'dynamicNode' , 
245+             name : 'p5. dynamicNode' , 
227246          } , 
228247          arguments : [ node . left ] 
229248        } 
@@ -1012,7 +1031,7 @@ function shadergenerator(p5, fn) {
10121031    return  length 
10131032  } 
10141033
1015-   fn . dynamicNode  =  function  ( input )  { 
1034+   p5 . dynamicNode  =  function  ( input )  { 
10161035    if  ( isShaderNode ( input ) )  { 
10171036      return  input ; 
10181037    } 
@@ -1025,8 +1044,8 @@ function shadergenerator(p5, fn) {
10251044  } 
10261045
10271046  // For replacing unary expressions 
1028-   fn . unaryNode  =  function ( input ,  sign )  { 
1029-     input  =  dynamicNode ( input ) ; 
1047+   p5 . unaryNode  =  function ( input ,  sign )  { 
1048+     input  =  p5 . dynamicNode ( input ) ; 
10301049    return  dynamicAddSwizzleTrap ( new  UnaryExpressionNode ( input ,  sign ) ) ; 
10311050  } 
10321051
@@ -1133,6 +1152,7 @@ function shadergenerator(p5, fn) {
11331152      } 
11341153
11351154      const  windowOverrides  =  { } ; 
1155+       const  fnOverrides  =  { } ; 
11361156
11371157      Object . keys ( availableHooks ) . forEach ( ( hookName )  =>  { 
11381158        const  hookTypes  =  originalShader . hookTypes ( hookName ) ; 
@@ -1168,7 +1188,7 @@ function shadergenerator(p5, fn) {
11681188          // If the expected return type is a struct we need to evaluate each of its properties 
11691189          if  ( ! isGLSLNativeType ( expectedReturnType . typeName ) )  { 
11701190            Object . entries ( returnedValue ) . forEach ( ( [ propertyName ,  propertyNode ] )  =>  { 
1171-               propertyNode  =  dynamicNode ( propertyNode ) ; 
1191+               propertyNode  =  p5 . dynamicNode ( propertyNode ) ; 
11721192              toGLSLResults [ propertyName ]  =  propertyNode . toGLSLBase ( this . context ) ; 
11731193              this . context . updateComponents ( propertyNode ) ; 
11741194            } ) ; 
@@ -1218,18 +1238,25 @@ function shadergenerator(p5, fn) {
12181238          this . resetGLSLContext ( ) ; 
12191239        } 
12201240        windowOverrides [ hookTypes . name ]  =  window [ hookTypes . name ] ; 
1241+         fnOverrides [ hookTypes . name ]  =  fn [ hookTypes . name ] ; 
12211242
12221243        // Expose the Functions to global scope for users to use 
12231244        window [ hookTypes . name ]  =  function ( userOverride )  { 
12241245          GLOBAL_SHADER [ hookTypes . name ] ( userOverride ) ; 
12251246        } ; 
1247+         fn [ hookTypes . name ]  =  function ( userOverride )  { 
1248+           GLOBAL_SHADER [ hookTypes . name ] ( userOverride ) ; 
1249+         } ; 
12261250      } ) ; 
12271251
12281252
12291253      this . cleanup  =  ( )  =>  { 
12301254        for  ( const  key  in  windowOverrides )  { 
12311255          window [ key ]  =  windowOverrides [ key ] ; 
12321256        } 
1257+         for  ( const  key  in  fnOverrides )  { 
1258+           fn [ key ]  =  fnOverrides [ key ] ; 
1259+         } 
12331260      } ; 
12341261    } 
12351262
@@ -1638,14 +1665,14 @@ function shadergenerator(p5, fn) {
16381665    if  ( ! GLOBAL_SHADER ?. isGenerating )  { 
16391666      return  originalNoise . apply ( this ,  args ) ;  // fallback to regular p5.js noise 
16401667    } 
1641-      
1668+ 
16421669    GLOBAL_SHADER . output . vertexDeclarations . add ( noiseGLSL ) ; 
16431670    GLOBAL_SHADER . output . fragmentDeclarations . add ( noiseGLSL ) ; 
16441671    return  fnNodeConstructor ( 'noise' ,  args ,  {  args : [ 'vec2' ] ,  returnType : 'float'  } ) ; 
16451672  } ; 
16461673} 
1647-    
1648-    
1674+ 
1675+ 
16491676export  default  shadergenerator ; 
16501677
16511678if  ( typeof  p5  !==  'undefined' )  { 
0 commit comments