Show the type an arithmetic shader node really puts out (#219)
The result of Add, Multiply, Mix and the other arithmetic nodes of a shader graph was drawn as any, whatever went in. The compiler already lifts a colour on any side to a colour result, so the pin said less than the code knew. A colour result could also be wired into a number input, and the shader then failed to compile. - liftedType in core/shader/nodes.ts is the one rule. The compiler reads it when it lifts two operands, and the editor reads it through liftedPortType for the ports it draws. - A SharedPortGroup may bring its own rule as agree. Without one it is agreedType, as before. The thirteen arithmetic nodes share their type by liftedPortType. - Only the any inputs decide. An input nothing feeds counts as the number typed into it. t, edge, exponent, min and max have no say. - The type travels through a chain of such nodes without code of its own, because #210 hands a shared type on. - In a ring the result stays any, unless a colour has settled it. - A number may feed a colour input. Without that a number result no longer fitted Output.color, although the compiler spreads it over three channels. The rule sits in portsCompatible, but only the shader graph has colour ports. - A colour result no longer fits a number input. An edge laid before the colour came in stays and is drawn in the danger colour, and the node at its end names the problem. - The nine shaders in the stored projects (108 edges) all stay valid under the new rule. Tests: - Gate on melektaus-atx: 212 files, 3260 tests (3240 + 20), exit 0. The gate right before this commit ran on the tree of this and the next commit together, with the same numbers. - e2e 28 on melektaus-atx: 81 checks, all pass. - e2e 1-31: 1059 pass, 1 fail in module 18 (the editor clock read 1.97 s after a stop). A rerun of 1-18 passed with 602 checks and 0.18 s. 1-31 was not run in full again. - No full run and no smokes. The sum of 1676 (1673 + 3) is reckoned. - Twenty unit tests in shader-port-types.test.ts, one of them runs all thirteen nodes through every mix of number and colour and compares what is drawn with the code made. - Two tests in shaders.test.ts now lay the edge first and bring the colour in after, the only order that still wires such a graph. - Three e2e checks in module 28 with the real mouse: a colour into Multiply, the red edge with its message, and the colour result refused at alpha and taken at color. - Fifteen unit counter-probes and two browser counter-probes all fail their tests. - Not checked in the browser: the one-input nodes, Mix and the ring, and a number wired straight into a colour input. Nothing was looked at after the build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9ca220a285
commit
f02adabcf9
9 files changed
+472
-10
No files matched your search
@@ -320,13 +320,14 @@ describe('compileShader', () => {
|
||||
expect(fragment).toContain('float alpha = clamp(n2_result, 0.0, 1.0);');
|
||||
expect(fragment).toContain('finalColor = vec4(clamp(rgb, 0.0, 1.0) * alpha, alpha);');
|
||||
|
||||
// A colour reaching the alpha port through an `any` result is the Output's problem.
|
||||
// A result wired to the alpha port while it was a number, and fed a colour afterwards, is the
|
||||
// Output's problem.
|
||||
const wrong = shaderEditor(f, 'Wrong');
|
||||
const texel = wrong.add(SHADER_TEXTURE_COLOR);
|
||||
const doubled = wrong.add('ShaderMultiply', { b: 2 });
|
||||
const out = wrong.add(SHADER_OUTPUT);
|
||||
wrong.link(texel, 'color', doubled, 'a');
|
||||
wrong.link(doubled, 'result', out, 'alpha');
|
||||
wrong.link(texel, 'color', doubled, 'a');
|
||||
const build = compileShader(wrong.asset().graph);
|
||||
expect(build.compiled).toBeNull();
|
||||
expect(build.problems).toEqual({ [out]: '"alpha" needs a number, not a color' });
|
||||
@@ -335,13 +336,14 @@ describe('compileShader', () => {
|
||||
it('names the problem on the node, and compiles nothing while there is one', () => {
|
||||
const f = makeProject();
|
||||
const s = shaderEditor(f);
|
||||
// A colour cannot be wired to a number port; a Multiply's `any` result can, and carries one.
|
||||
// A colour cannot be wired to a number port; a Multiply's result can while it is a number, and
|
||||
// the edge stays when a colour feeds the Multiply afterwards.
|
||||
const texel = s.add(SHADER_TEXTURE_COLOR);
|
||||
const doubled = s.add('ShaderMultiply', { b: 2 });
|
||||
const mixed = s.add('ShaderMix');
|
||||
const output = s.add(SHADER_OUTPUT);
|
||||
s.link(texel, 'color', doubled, 'a');
|
||||
s.link(doubled, 'result', mixed, 't');
|
||||
s.link(texel, 'color', doubled, 'a');
|
||||
s.link(mixed, 'result', output, 'color');
|
||||
let build = compileShader(s.asset().graph);
|
||||
expect(build.compiled).toBeNull();
|
||||
|
||||
Reference in new issue
Block a user