diff --git a/src/strands/ir_builders.js b/src/strands/ir_builders.js index 4ae69d90f4..0c4b139d75 100644 --- a/src/strands/ir_builders.js +++ b/src/strands/ir_builders.js @@ -344,38 +344,24 @@ export function castToFloat(strandsContext, dep) { return createStrandsNode(id, dimension, strandsContext); } -export function structConstructorNode(strandsContext, structTypeInfo, rawUserArgs) { +export function structConstructorNode(strandsContext, structTypeInfo, dependsOn) { const { cfg, dag } = strandsContext; - const { identifer, properties } = structTypeInfo; + const { properties } = structTypeInfo; - if (!(rawUserArgs.length === properties.length)) { + if (dependsOn.length !== properties.length) { FES.userError('type error', - `You've tried to construct a ${structTypeInfo.typeName} struct with ${rawUserArgs.length} properties, but it expects ${properties.length} properties.\n` + + `You've tried to construct a ${structTypeInfo.typeName} struct with ${dependsOn.length} properties, but it expects ${properties.length} properties.\n` + `The properties it expects are:\n` + - `${properties.map(prop => prop.name + ' ' + prop.DataType.baseType + prop.DataType.dimension)}` + `${properties.map(prop => `${prop.name}: ${prop.dataType.baseType}${prop.dataType.dimension}`).join(', ')}` ); } - const dependsOn = []; - for (let i = 0; i < properties.length; i++) { - const expectedProperty = properties[i]; - const { originalNodeID, mappedDependencies } = mapPrimitiveDepsToIDs(strandsContext, expectedProperty.dataType, rawUserArgs[i]); - if (originalNodeID) { - dependsOn.push(originalNodeID); - } - else { - dependsOn.push( - constructTypeFromIDs(strandsContext, expectedProperty.dataType, mappedDependencies) - ); - } - } - const nodeData = DAG.createNodeData({ nodeType: NodeType.OPERATION, opCode: OpCode.Nary.CONSTRUCTOR, dimension: properties.length, - baseType: structTypeInfo.typeName , - dependsOn + baseType: structTypeInfo.typeName, + dependsOn, }); const id = DAG.getOrCreateNode(dag, nodeData); CFG.recordInBasicBlock(cfg, cfg.currentBlock, id); diff --git a/src/webgl/strands_glslBackend.js b/src/webgl/strands_glslBackend.js index bbd05a5950..75bd44a2c1 100644 --- a/src/webgl/strands_glslBackend.js +++ b/src/webgl/strands_glslBackend.js @@ -249,7 +249,7 @@ export const glslBackend = { } const dag = strandsContext.dag; const rootNode = getNodeDataFromID(dag, rootNodeID); - if (isStructType(returnType)) { + if (isStructType(returnType) && rootNode.identifier) { const structTypeInfo = returnType; for (let i = 0; i < structTypeInfo.properties.length; i++) { const prop = structTypeInfo.properties[i]; diff --git a/src/webgpu/strands_wgslBackend.js b/src/webgpu/strands_wgslBackend.js index 79d0f2816b..0ba1c29772 100644 --- a/src/webgpu/strands_wgslBackend.js +++ b/src/webgpu/strands_wgslBackend.js @@ -410,7 +410,7 @@ export const wgslBackend = { } const dag = strandsContext.dag; const rootNode = getNodeDataFromID(dag, rootNodeID); - if (isStructType(returnType)) { + if (isStructType(returnType) && rootNode.identifier) { const structTypeInfo = returnType; for (let i = 0; i < structTypeInfo.properties.length; i++) { const prop = structTypeInfo.properties[i]; diff --git a/test/unit/visual/cases/webgl.js b/test/unit/visual/cases/webgl.js index 40dd436481..972d9bc5f0 100644 --- a/test/unit/visual/cases/webgl.js +++ b/test/unit/visual/cases/webgl.js @@ -1500,6 +1500,25 @@ visualTest('randomGaussian() in a fragment loop averages to the mean', (p5, scre p5.circle(0, 0, 30); screenshot(); }); + + visualTest('hook returning a fresh struct (not the struct argument) applies modifications', (p5, screenshot) => { + p5.createCanvas(50, 50, p5.WEBGL); + const shader = p5.baseMaterialShader().modify(() => { + p5.worldInputs.begin(); + p5.worldInputs.set({ + position: p5.worldInputs.position.add([10, 0, 0]), + normal: p5.worldInputs.normal, + texCoord: p5.worldInputs.texCoord, + color: [1, 0, 0, 1], + }); + p5.worldInputs.end(); + }, { p5 }); + p5.background(0); + p5.noStroke(); + p5.shader(shader); + p5.plane(20, 20); + screenshot(); + }); }); visualSuite('background()', function () { diff --git a/test/unit/visual/cases/webgpu.js b/test/unit/visual/cases/webgpu.js index 0e84359858..4fc098850b 100644 --- a/test/unit/visual/cases/webgpu.js +++ b/test/unit/visual/cases/webgpu.js @@ -364,6 +364,25 @@ visualSuite("WebGPU", function () { p5.plane(50, 50); await screenshot(); }); + + visualTest('hook returning a fresh struct (not the struct argument) applies modifications', async function(p5, screenshot) { + await p5.createCanvas(50, 50, p5.WEBGPU); + const shader = p5.baseMaterialShader().modify(() => { + p5.worldInputs.begin(); + p5.worldInputs.set({ + position: p5.worldInputs.position.add([10, 0, 0]), + normal: p5.worldInputs.normal, + texCoord: p5.worldInputs.texCoord, + color: [1, 0, 0, 1], + }); + p5.worldInputs.end(); + }, { p5 }); + p5.background(0); + p5.noStroke(); + p5.shader(shader); + p5.plane(20, 20); + await screenshot(); + }, { focus: true }); }); visualTest('randomGaussian() colors a basic shader (WebGPU)', async function(p5, screenshot) { diff --git a/test/unit/visual/screenshots/WebGL/p5.strands/hook returning a fresh struct (not the struct argument) applies modifications/000.png b/test/unit/visual/screenshots/WebGL/p5.strands/hook returning a fresh struct (not the struct argument) applies modifications/000.png new file mode 100644 index 0000000000..b4cb0984a7 Binary files /dev/null and b/test/unit/visual/screenshots/WebGL/p5.strands/hook returning a fresh struct (not the struct argument) applies modifications/000.png differ diff --git a/test/unit/visual/screenshots/WebGL/p5.strands/hook returning a fresh struct (not the struct argument) applies modifications/metadata.json b/test/unit/visual/screenshots/WebGL/p5.strands/hook returning a fresh struct (not the struct argument) applies modifications/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/WebGL/p5.strands/hook returning a fresh struct (not the struct argument) applies modifications/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/WebGPU/Shaders/hook returning a fresh struct (not the struct argument) applies modifications/000.png b/test/unit/visual/screenshots/WebGPU/Shaders/hook returning a fresh struct (not the struct argument) applies modifications/000.png new file mode 100644 index 0000000000..b4cb0984a7 Binary files /dev/null and b/test/unit/visual/screenshots/WebGPU/Shaders/hook returning a fresh struct (not the struct argument) applies modifications/000.png differ diff --git a/test/unit/visual/screenshots/WebGPU/Shaders/hook returning a fresh struct (not the struct argument) applies modifications/metadata.json b/test/unit/visual/screenshots/WebGPU/Shaders/hook returning a fresh struct (not the struct argument) applies modifications/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/WebGPU/Shaders/hook returning a fresh struct (not the struct argument) applies modifications/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file