Skip to content

Commit b511667

Browse files
committed
Pass context in as a parameter to avoid minification issues
1 parent 7fa997e commit b511667

4 files changed

Lines changed: 66 additions & 49 deletions

File tree

src/core/filterShaders.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as constants from './constants';
66
export function makeFilterShader(renderer, operation, p5) {
77
switch (operation) {
88
case constants.GRAY:
9-
return renderer.baseFilterShader().modify(() => {
9+
return renderer.baseFilterShader().modify(({ p5 }) => {
1010
p5.getColor((inputs, canvasContent) => {
1111
const tex = p5.getTexture(canvasContent, inputs.texCoord);
1212
// weighted grayscale with luminance values
@@ -16,7 +16,7 @@ export function makeFilterShader(renderer, operation, p5) {
1616
}, { p5 });
1717

1818
case constants.INVERT:
19-
return renderer.baseFilterShader().modify(() => {
19+
return renderer.baseFilterShader().modify(({ p5 }) => {
2020
p5.getColor((inputs, canvasContent) => {
2121
const color = p5.getTexture(canvasContent, inputs.texCoord);
2222
const invertedColor = p5.vec3(1.0) - color.rgb;
@@ -25,7 +25,7 @@ export function makeFilterShader(renderer, operation, p5) {
2525
}, { p5 });
2626

2727
case constants.THRESHOLD:
28-
return renderer.baseFilterShader().modify(() => {
28+
return renderer.baseFilterShader().modify(({ p5 }) => {
2929
const filterParameter = p5.uniformFloat();
3030
p5.getColor((inputs, canvasContent) => {
3131
const color = p5.getTexture(canvasContent, inputs.texCoord);
@@ -38,7 +38,7 @@ export function makeFilterShader(renderer, operation, p5) {
3838
}, { p5 });
3939

4040
case constants.POSTERIZE:
41-
return renderer.baseFilterShader().modify(() => {
41+
return renderer.baseFilterShader().modify(({ p5 }) => {
4242
const filterParameter = p5.uniformFloat();
4343
const quantize = (color, n) => {
4444
// restrict values to N options/bins
@@ -60,7 +60,7 @@ export function makeFilterShader(renderer, operation, p5) {
6060
}, { p5 });
6161

6262
case constants.BLUR:
63-
return renderer.baseFilterShader().modify(() => {
63+
return renderer.baseFilterShader().modify(({ p5 }) => {
6464
const radius = p5.uniformFloat();
6565
const direction = p5.uniformVec2();
6666

@@ -120,7 +120,7 @@ export function makeFilterShader(renderer, operation, p5) {
120120
}, { p5 });
121121

122122
case constants.ERODE:
123-
return renderer.baseFilterShader().modify(() => {
123+
return renderer.baseFilterShader().modify(({ p5 }) => {
124124
const luma = (color) => {
125125
return p5.dot(color.rgb, p5.vec3(0.2126, 0.7152, 0.0722));
126126
};
@@ -150,7 +150,7 @@ export function makeFilterShader(renderer, operation, p5) {
150150
}, { p5 });
151151

152152
case constants.DILATE:
153-
return renderer.baseFilterShader().modify(() => {
153+
return renderer.baseFilterShader().modify(({ p5 }) => {
154154
const luma = (color) => {
155155
return p5.dot(color.rgb, p5.vec3(0.2126, 0.7152, 0.0722));
156156
};
@@ -180,7 +180,7 @@ export function makeFilterShader(renderer, operation, p5) {
180180
}, { p5 });
181181

182182
case constants.OPAQUE:
183-
return renderer.baseFilterShader().modify(() => {
183+
return renderer.baseFilterShader().modify(({ p5 }) => {
184184
p5.getColor((inputs, canvasContent) => {
185185
const color = p5.getTexture(canvasContent, inputs.texCoord);
186186
return p5.vec4(color.rgb, 1.0);

src/core/p5.Renderer3D.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1911,7 +1911,7 @@ export class Renderer3D extends Renderer {
19111911
_getSphereMapping(img) {
19121912
if (!this.sphereMapping) {
19131913
const p5 = this._pInst;
1914-
this.sphereMapping = this.baseFilterShader().modify(() => {
1914+
this.sphereMapping = this.baseFilterShader().modify(({ p5 }) => {
19151915
const uEnvMap = p5.uniformTexture();
19161916
const uFovY = p5.uniformFloat();
19171917
const uAspect = p5.uniformFloat();

src/strands/p5.strands.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ function strands(p5, fn) {
7575

7676
p5.Shader.prototype.modify = function (shaderModifier, scope = {}) {
7777
try {
78-
if (shaderModifier instanceof Function) {
78+
if (shaderModifier instanceof Function || typeof shaderModifier === 'string') {
7979
// Reset the context object every time modify is called;
8080
// const backend = glslBackend;
8181
initStrandsContext(strandsContext, this._renderer.strandsBackend, {
@@ -92,7 +92,9 @@ function strands(p5, fn) {
9292
if (options.parser) {
9393
// #7955 Wrap function declaration code in brackets so anonymous functions are not top level statements, which causes an error in acorn when parsing
9494
// https://github.com/acornjs/acorn/issues/1385
95-
const sourceString = `(${shaderModifier.toString()})`;
95+
const sourceString = typeof shaderModifier === 'string'
96+
? `(${shaderModifier})`
97+
: `(${shaderModifier.toString()})`;
9698
strandsCallback = transpileStrandsToJS(
9799
p5,
98100
sourceString,

src/strands/strands_transpiler.js

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,19 @@ const ASTCallbacks = {
130130
if (ancestors.some(nodeIsUniform)) { return; }
131131
if (_state.varyings[node.name]
132132
&& !ancestors.some(a => a.type === 'AssignmentExpression' && a.left === node)) {
133-
node.type = 'ExpressionStatement';
134-
node.expression = {
135-
type: 'CallExpression',
136-
callee: {
137-
type: 'MemberExpression',
138-
object: {
139-
type: 'Identifier',
140-
name: node.name
141-
},
142-
property: {
143-
type: 'Identifier',
144-
name: 'getValue'
145-
},
133+
node.type = 'CallExpression';
134+
node.callee = {
135+
type: 'MemberExpression',
136+
object: {
137+
type: 'Identifier',
138+
name: node.name
146139
},
147-
arguments: [],
148-
}
140+
property: {
141+
type: 'Identifier',
142+
name: 'getValue'
143+
},
144+
};
145+
node.arguments = [];
149146
}
150147
},
151148
// The callbacks for AssignmentExpression and BinaryExpression handle
@@ -208,13 +205,12 @@ const ASTCallbacks = {
208205
varyingName = node.left.object.name;
209206
}
210207
// Check if it's a getValue() call: myVarying.getValue().xyz
211-
else if (node.left.object.type === 'ExpressionStatement' &&
212-
node.left.object.expression?.type === 'CallExpression' &&
213-
node.left.object.expression.callee?.type === 'MemberExpression' &&
214-
node.left.object.expression.callee.property?.name === 'getValue' &&
215-
node.left.object.expression.callee.object?.type === 'Identifier' &&
216-
_state.varyings[node.left.object.expression.callee.object.name]) {
217-
varyingName = node.left.object.expression.callee.object.name;
208+
else if (node.left.object.type === 'CallExpression' &&
209+
node.left.object.callee?.type === 'MemberExpression' &&
210+
node.left.object.callee.property?.name === 'getValue' &&
211+
node.left.object.callee.object?.type === 'Identifier' &&
212+
_state.varyings[node.left.object.callee.object.name]) {
213+
varyingName = node.left.object.callee.object.name;
218214
}
219215

220216
if (varyingName) {
@@ -564,7 +560,7 @@ const ASTCallbacks = {
564560

565561
// Transform for statement into strandsFor() call
566562
// for (init; test; update) body -> strandsFor(initCb, conditionCb, updateCb, bodyCb, initialVars)
567-
563+
568564
// Generate unique loop variable name
569565
const uniqueLoopVar = `loopVar${loopVarCounter++}`;
570566

@@ -928,7 +924,7 @@ const ASTCallbacks = {
928924
// Reset counters at the start of each transpilation
929925
blockVarCounter = 0;
930926
loopVarCounter = 0;
931-
927+
932928
const ast = parse(sourceString, {
933929
ecmaVersion: 2021,
934930
locations: srcLocations
@@ -961,18 +957,37 @@ const ASTCallbacks = {
961957
recursive(ast, { varyings: {} }, postOrderControlFlowTransform);
962958
const transpiledSource = escodegen.generate(ast);
963959
const scopeKeys = Object.keys(scope);
964-
const internalStrandsCallback = new Function(
965-
// Create a parameter called __p5, not just p5, because users of instance mode
966-
// may pass in a variable called p5 as a scope variable. If we rely on a variable called
967-
// p5, then the scope variable called p5 might accidentally override internal function
968-
// calls to p5 static methods.
969-
'__p5',
970-
...scopeKeys,
971-
transpiledSource
972-
.slice(
973-
transpiledSource.indexOf('{') + 1,
974-
transpiledSource.lastIndexOf('}')
975-
).replaceAll(';', '')
976-
);
977-
return () => internalStrandsCallback(p5, ...scopeKeys.map(key => scope[key]));
960+
const match = /\(?\s*(?:function)?\s*\(([^)]*)\)\s*(?:=>)?\s*{((?:.|\n)*)}\s*;?\s*\)?/
961+
.exec(transpiledSource);
962+
if (!match) {
963+
console.log(transpiledSource);
964+
throw new Error('Could not parse p5.strands function!');
965+
}
966+
const params = match[1].split(/,\s*/).filter(param => !!param.trim());
967+
let paramVals, paramNames;
968+
if (params.length > 0) {
969+
paramNames = params;
970+
paramVals = [scope];
971+
} else {
972+
paramNames = scopeKeys;
973+
paramVals = scopeKeys.map(key => scope[key]);
974+
}
975+
const body = match[2];
976+
try {
977+
const internalStrandsCallback = new Function(
978+
// Create a parameter called __p5, not just p5, because users of instance mode
979+
// may pass in a variable called p5 as a scope variable. If we rely on a variable called
980+
// p5, then the scope variable called p5 might accidentally override internal function
981+
// calls to p5 static methods.
982+
'__p5',
983+
...paramNames,
984+
body,
985+
);
986+
return () => internalStrandsCallback(p5, ...paramVals);
987+
} catch (e) {
988+
console.error(e);
989+
console.log(paramNames);
990+
console.log(body);
991+
throw new Error('Error transpiling p5.strands callback!');
992+
}
978993
}

0 commit comments

Comments
 (0)