Skip to content

Commit b1c0834

Browse files
authored
Merge branch 'dev-2.0' into webgpu-perf
2 parents 718698e + ee063c6 commit b1c0834

5 files changed

Lines changed: 124 additions & 0 deletions

File tree

src/strands/strands_api.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,86 @@ import * as FES from './strands_FES'
2121
import { getNodeDataFromID } from './ir_dag'
2222
import { StrandsNode, createStrandsNode } from './strands_node'
2323

24+
const BUILTIN_GLOBAL_SPECS = {
25+
width: { typeInfo: DataType.float1, get: (p) => p.width },
26+
height: { typeInfo: DataType.float1, get: (p) => p.height },
27+
mouseX: { typeInfo: DataType.float1, get: (p) => p.mouseX },
28+
mouseY: { typeInfo: DataType.float1, get: (p) => p.mouseY },
29+
pmouseX: { typeInfo: DataType.float1, get: (p) => p.pmouseX },
30+
pmouseY: { typeInfo: DataType.float1, get: (p) => p.pmouseY },
31+
winMouseX: { typeInfo: DataType.float1, get: (p) => p.winMouseX },
32+
winMouseY: { typeInfo: DataType.float1, get: (p) => p.winMouseY },
33+
pwinMouseX: { typeInfo: DataType.float1, get: (p) => p.pwinMouseX },
34+
pwinMouseY: { typeInfo: DataType.float1, get: (p) => p.pwinMouseY },
35+
frameCount: { typeInfo: DataType.float1, get: (p) => p.frameCount },
36+
deltaTime: { typeInfo: DataType.float1, get: (p) => p.deltaTime },
37+
displayWidth: { typeInfo: DataType.float1, get: (p) => p.displayWidth },
38+
displayHeight: { typeInfo: DataType.float1, get: (p) => p.displayHeight },
39+
windowWidth: { typeInfo: DataType.float1, get: (p) => p.windowWidth },
40+
windowHeight: { typeInfo: DataType.float1, get: (p) => p.windowHeight },
41+
mouseIsPressed: { typeInfo: DataType.bool1, get: (p) => p.mouseIsPressed },
42+
}
43+
44+
function _getBuiltinGlobalsCache(strandsContext) {
45+
if (!strandsContext._builtinGlobals || strandsContext._builtinGlobals.dag !== strandsContext.dag) {
46+
strandsContext._builtinGlobals = {
47+
dag: strandsContext.dag,
48+
nodes: new Map(),
49+
uniformsAdded: new Set(),
50+
}
51+
}
52+
// return the cache
53+
return strandsContext._builtinGlobals
54+
}
55+
56+
function getBuiltinGlobalNode(strandsContext, name) {
57+
const spec = BUILTIN_GLOBAL_SPECS[name]
58+
if (!spec) return null
59+
60+
const cache = _getBuiltinGlobalsCache(strandsContext)
61+
const uniformName = `_p5_global_${name}`
62+
const cached = cache.nodes.get(uniformName)
63+
if (cached) return cached
64+
65+
if (!cache.uniformsAdded.has(uniformName)) {
66+
cache.uniformsAdded.add(uniformName)
67+
strandsContext.uniforms.push({
68+
name: uniformName,
69+
typeInfo: spec.typeInfo,
70+
defaultValue: () => {
71+
const p5Instance = strandsContext.renderer?._pInst || strandsContext.p5?.instance
72+
return p5Instance ? spec.get(p5Instance) : undefined
73+
},
74+
})
75+
}
76+
77+
const { id, dimension } = build.variableNode(strandsContext, spec.typeInfo, uniformName)
78+
const node = createStrandsNode(id, dimension, strandsContext)
79+
node._originalBuiltinName = name
80+
cache.nodes.set(uniformName, node)
81+
return node
82+
}
83+
84+
function installBuiltinGlobalAccessors(strandsContext) {
85+
if (strandsContext._builtinGlobalsAccessorsInstalled) return
86+
87+
const getRuntimeP5Instance = () => strandsContext.renderer?._pInst || strandsContext.p5?.instance
88+
89+
for (const name of Object.keys(BUILTIN_GLOBAL_SPECS)) {
90+
const spec = BUILTIN_GLOBAL_SPECS[name]
91+
Object.defineProperty(window, name, {
92+
get: () => {
93+
if (strandsContext.active) {
94+
return getBuiltinGlobalNode(strandsContext, name);
95+
}
96+
const inst = getRuntimeP5Instance()
97+
return spec.get(inst);
98+
},
99+
})
100+
}
101+
strandsContext._builtinGlobalsAccessorsInstalled = true
102+
}
103+
24104
//////////////////////////////////////////////
25105
// User nodes
26106
//////////////////////////////////////////////
@@ -419,6 +499,8 @@ function enforceReturnTypeMatch(strandsContext, expectedType, returned, hookName
419499
return returnedNodeID;
420500
}
421501
export function createShaderHooksFunctions(strandsContext, fn, shader) {
502+
installBuiltinGlobalAccessors(strandsContext)
503+
422504
// Add shader context to hooks before spreading
423505
const vertexHooksWithContext = Object.fromEntries(
424506
Object.entries(shader.hooks.vertex).map(([name, hook]) => [name, { ...hook, shaderContext: 'vertex' }])

test/unit/visual/cases/webgl.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,24 @@ visualSuite('WebGL', function() {
10221022
screenshot();
10231023
});
10241024

1025+
visualTest('uses width/height in getFinalColor', (p5, screenshot) => {
1026+
let firstShader;
1027+
function firstShaderCallback() {
1028+
getFinalColor((color) => {
1029+
color = [width / 60, height / 60, 0, 1];
1030+
return color;
1031+
});
1032+
}
1033+
p5.createCanvas(60, 60, p5.WEBGL);
1034+
p5.pixelDensity(1);
1035+
firstShader = p5.baseColorShader().modify(firstShaderCallback);
1036+
p5.background(0);
1037+
p5.shader(firstShader);
1038+
p5.noStroke();
1039+
p5.plane(20, 20);
1040+
screenshot();
1041+
});
1042+
10251043
visualSuite('auto-return for shader hooks', () => {
10261044
visualTest('auto-returns input struct when return is omitted', (p5, screenshot) => {
10271045
p5.createCanvas(50, 50, p5.WEBGL);
284 Bytes
Loading
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"numScreenshots": 1
3+
}

test/unit/webgl/p5.Shader.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,27 @@ suite('p5.Shader', function() {
447447
}).not.toThrowError();
448448
});
449449

450+
test('returns numbers for builtin globals outside hooks and a strandNode when called inside hooks', () => {
451+
myp5.createCanvas(5, 5, myp5.WEBGL);
452+
myp5.baseMaterialShader().modify(() => {
453+
myp5.getPixelInputs(inputs => {
454+
const mxInHook = window.mouseX;
455+
const wInHook = window.width;
456+
assert.isTrue(mxInHook.isStrandsNode);
457+
assert.isTrue(wInHook.isStrandsNode);
458+
inputs.color = [1, 0, 0, 1];
459+
return inputs;
460+
});
461+
}, { myp5 });
462+
463+
const mx = window.mouseX;
464+
const w = window.width;
465+
assert.isNumber(mx);
466+
assert.isNumber(w);
467+
assert.strictEqual(w, myp5.width);
468+
});
469+
470+
450471
test('handle custom uniform names with automatic values', () => {
451472
myp5.createCanvas(50, 50, myp5.WEBGL);
452473
const testShader = myp5.baseMaterialShader().modify(() => {

0 commit comments

Comments
 (0)