A name that a sprite already owns cannot name a property, and a division by zero cannot answer (#63, #64)
game-maker / suite (push) Failing after 11m29s
game-maker / suite (push) Failing after 11m29s
#63: a shader Property node named "width" quietly took over the sprite row of the same name. isSpriteProp lives in PropertySchema now and is derived from FULL_SCHEMAS.sprite instead of being a second list that drifts. isValidPropertyName rejects those ten names, and the compiler reports it at the node as its own problem: "width" is a sprite property, told apart from "not a word" and from a duplicate. #64: Divide emitted (a / b) and handed NaN to the driver. It emits divide(a, b) now, with the guard in the prologue next to straight(), scalar and per channel: zero divided by zero is zero. That was already the house rule in the behavior and particle graphs - only the shader had never been told. Clamp comes along as a shader node for the same reason: the behavior catalog has had it all along.
This commit is contained in:
1 parent
150f2e0906
commit
c990dbcb26
6 files changed
+203
-6
No files matched your search
@@ -546,6 +546,82 @@ export async function shader(t) {
|
||||
{ foldLeft, foldMiddle, foldRight },
|
||||
);
|
||||
|
||||
// 28k-iv. A property named like a row the sprite has anyway is a problem on the node (#63): both
|
||||
// rows would sit on the same bag key and the uniform would read the sprite's width, 160 here,
|
||||
// instead of the default the node declares. Renaming it compiles the same graph.
|
||||
const namedProperty = (name) =>
|
||||
graph(
|
||||
[
|
||||
node('named', 'ShaderProperty', { name, default: 0.25, min: 0, max: 1 }),
|
||||
node('red', 'ShaderColor', { value: 0xff0000 }, 260, 200),
|
||||
node('dim', 'ShaderMultiply', {}, 520, 0),
|
||||
node('out', 'ShaderOutput', {}, 780, 0),
|
||||
],
|
||||
[
|
||||
edge('named', 'value', 'dim', 'b'),
|
||||
edge('red', 'color', 'dim', 'a'),
|
||||
edge('dim', 'result', 'out', 'color'),
|
||||
],
|
||||
);
|
||||
await namedProperty('width');
|
||||
await sleep(400);
|
||||
const spriteProp = await info();
|
||||
check(
|
||||
'a property named like a sprite row is a problem on the node, not a second width row (#63)',
|
||||
(await json("__gm.shader.nodeProblem('named')")) === '"width" is a sprite property' &&
|
||||
spriteProp === '"width" is a sprite property',
|
||||
JSON.stringify({ spriteProp, problem: await json("__gm.shader.nodeProblem('named')") }),
|
||||
);
|
||||
await namedProperty('amount');
|
||||
await sleep(400);
|
||||
check(
|
||||
'the same graph under a free name compiles: a quarter of the red',
|
||||
(await info()) === '1 property' && colourDistance(await pixel(-0.3, -0.3), '#400000') < 6,
|
||||
JSON.stringify({ info: await info(), pixel: await pixel(-0.3, -0.3) }),
|
||||
);
|
||||
|
||||
// 28k-v. Dividing by zero has an answer (#64). `a / 0.0` is NaN, and the epilog's clamp(NaN) is
|
||||
// undefined in GLSL – the pixel would be the driver's choice. The guard makes it 0, so the sprite
|
||||
// goes black instead of "whatever this machine does".
|
||||
const dividedBy = (value) =>
|
||||
graph(
|
||||
[
|
||||
node('red', 'ShaderColor', { value: 0xff0000 }),
|
||||
node('by', 'ShaderNumber', { value }, 260, 200),
|
||||
node('div', 'ShaderDivide', {}, 520, 0),
|
||||
node('out', 'ShaderOutput', {}, 780, 0),
|
||||
],
|
||||
[
|
||||
edge('red', 'color', 'div', 'a'),
|
||||
edge('by', 'value', 'div', 'b'),
|
||||
edge('div', 'result', 'out', 'color'),
|
||||
],
|
||||
);
|
||||
await dividedBy(2);
|
||||
await sleep(400);
|
||||
const halved = await pixel(-0.3, -0.3);
|
||||
await dividedBy(0);
|
||||
await sleep(400);
|
||||
const byZero = await pixel(-0.3, -0.3);
|
||||
check(
|
||||
'Divide by 2 halves the red, and dividing by 0 is 0 – a black pixel, not the driver’s choice (#64)',
|
||||
colourDistance(halved, '#800000') < 6 && colourDistance(byZero, '#000000') < 6,
|
||||
JSON.stringify({ halved, byZero }),
|
||||
);
|
||||
|
||||
// 28k-vi. Clamp holds a value inside a range, per channel for a colour.
|
||||
await graph(
|
||||
[
|
||||
node('red', 'ShaderColor', { value: 0xff0000 }),
|
||||
node('hold', 'ShaderClamp', { min: 0, max: 0.25 }, 260, 0),
|
||||
node('out', 'ShaderOutput', {}, 520, 0),
|
||||
],
|
||||
[edge('red', 'color', 'hold', 'value'), edge('hold', 'result', 'out', 'color')],
|
||||
);
|
||||
await sleep(400);
|
||||
const held = await pixel(-0.3, -0.3);
|
||||
check('Clamp at 0..0.25 holds full red down to a quarter', colourDistance(held, '#400000') < 6, held);
|
||||
|
||||
// 28l. Sample texture reads the picture where the graph says. On a pasted two-colour picture:
|
||||
// flipped u swaps the halves; u + 0.5 past the border shows the Output's Edge – Repeat continues
|
||||
// with the far half, Mirror with the near one.
|
||||
|
||||
Reference in new issue
Block a user