A calculation needed in several shaders (a greyscale, a noise, an
outline) had to be built again in every one of them. A shader
function keeps it as an asset of its own, called like a behavior is
since #16.
- New asset type `shaderfunction` ("Shader function"), edited in the
Shader tab. The panel beside the graph shows no picture, the
readout counts its inputs and outputs.
- Two new nodes: `Function input` and `Function output`. Their
declared ports, numbers or colours only, are the ports of every
call. One of each per function, like Start and End.
- The call is node `ShaderCall`, named after the function. The
palette lists every function, it can be dragged in from the Assets
panel, and a double-click opens it.
- The compiler sets the function in where it is called
(`inlineFunctions`). It renames the copied nodes `<call>/<node>`
and turns an unconnected port into a constant. Passes, Time, the
Edge cut and the corner walk then see a plain graph.
- A problem inside a function is reported at the call, in the
function's words. The function's own tab checks it on its own
(`checkShaderFunction`).
- `ShaderLibrary` keys a shader on its graph and on every function it
calls, however deep, so a change reaches every caller.
- The port commands mirror a new, renamed or removed port into every
call, as for a behavior's Start and End. `NodeDef.portKinds` holds
the two ends to Number and Color.
- As agreed in the issue: no `Property`, `Color property`, Output or
Vertex output in a function, and `Time` is the caller's clock.
- Own decision: a `Pass` may stand in a function. It becomes a pass
of the calling shader, so a wide blur can be a function.
- A function calling itself, also through another, says so at the
node and is not set in. The palette does not offer such a call.
- The Shader tab showed only the compiler's problems. A call nothing
reaches was never compiled and looked healthy, so a call now also
shows its own problem there, as in a behavior.
Tests:
- Gate: 228 files, 3510 tests, CHECK EXIT 0 (+13: 11 in
tests/core/shader-functions.test.ts, 2 for the new icon)
- e2e 28: 100 checks, all passed (+3 in 28l-viii). Called and in
place both #606060/#a2a2a2, halved in the function #303030/#515151.
- Counter-check: a fingerprint without the called functions fails 1
unit test, and in the browser the change check (#606060 stays).
- The first e2e runs found two faults, both fixed: a double-click
only selected the function, and an unreached call of itself
showed no problem.
- e2e total 1728 is computed (1725 + 3).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>