Shader support #62

Closed
opened 2026-09-12 21:18:48 +02:00 by admin · 2 comments

Fraglich ob das funktioniert, aber ist es möglich dass man einem sprite einen shader zuweisen könnte.

  • Standard shader sollte im prinzip das sein was jetzt ist, einfach nur die texture so wie ist anzeigt
  • ein weiterer shader bei dem man brightness, contrast und saturation einstellen kann

vorerst einfach buildin shader - sprich man braucht nicht im editor selbst einen shader erstellen können

Fraglich ob das funktioniert, aber ist es möglich dass man einem sprite einen shader zuweisen könnte. - Standard shader sollte im prinzip das sein was jetzt ist, einfach nur die texture so wie ist anzeigt - ein weiterer shader bei dem man brightness, contrast und saturation einstellen kann vorerst einfach buildin shader - sprich man braucht nicht im editor selbst einen shader erstellen können
Owner

Built and merged as 42cafa7; wiki page Shaders in wiki commit a0fad88.

Decisions (user, 2026-09-12): not a built-in shader but a shader asset with a node graph and its own Shader tab; a sprite wears it through the Shader picker (None = no filter, no extra render pass); the rows below the picker are the graph's Property nodes; the node set is sized to rebuild "Adjust colors" (brightness, contrast, saturation, 1 = neutral) and nothing more. The prototype with a static registry (core/properties/shaders.ts + hand-written GLSL) was replaced, not kept.

What is in:

  • Asset type shader (not placeable, carries a Graph), Shader tab with picker, the Behavior canvas (right-click palette, edges, snap, fit, undo) and a readout N properties / the reason the graph does not compile; a broken node shows the reason on its body with a red frame.
  • Nodes: Texture color, Output (one per graph), Property, Color, Add/Subtract/Multiply/Divide, Mix, Luminance. Values are number (float) or vec3 (colour); math ports are any (a colour on either side makes the result a colour, a float is broadcast).
  • Compiler core/shader/compile.ts: one GLSL local per reachable node, uniform float u_<name> per Property, unpremultiply in the prelude, clamp and re-multiply in the epilogue. Fatal problems shown at the node: no Output, invalid/duplicate property name, cycle, colour into a number port.
  • Sprite rows come from the asset, so schemaForAsset, schemaForObject, resolveAssetProps, resolveSceneObjectProps, isModified, deviatesFromAsset, requirePropDef and friends now take the project (43 call sites). Override/Reset/Apply, gold marks and the Properties node work per property key; a value without a visible row stays stored but marks nothing.
  • "Adjust colors" is a graph of 11 nodes (tools/lib/shaders.mjs), shipped in the fixture and the three example games.

Proof: ./check.sh 850 tests, e2e step 28 (new) 29 checks, neighbouring modules 2/4/6/24/26 187 checks, Jump-Run/Tetris/Actor 24/19/20, bundle byte-identical after a rebuild. Pixels on #4080ff: brightness 0.5 #204080, contrast 0 #808080, saturation 0 #7c7c7c, all byte-exact; a red Color node hung into the Output recolours the sprite live. The full run is CI's after the push.

Not in this step: alpha input on Output, more nodes, a preview sprite in the tab, text objects. Follow-up (user, after looking at the Actor graph): brightness should work by Add, not Multiply, with all values at 1 still leaving the pixel untouched.

Built and merged as `42cafa7`; wiki page *Shaders* in wiki commit `a0fad88`. **Decisions (user, 2026-09-12):** not a built-in shader but a **shader asset with a node graph** and its own **Shader tab**; a sprite wears it through the `Shader` picker (`None` = no filter, no extra render pass); the rows below the picker are the graph's `Property` nodes; the node set is sized to rebuild "Adjust colors" (brightness, contrast, saturation, **1 = neutral**) and nothing more. The prototype with a static registry (`core/properties/shaders.ts` + hand-written GLSL) was replaced, not kept. **What is in:** - Asset type `shader` (not placeable, carries a `Graph`), Shader tab with picker, the Behavior canvas (right-click palette, edges, snap, fit, undo) and a readout `N properties` / the reason the graph does not compile; a broken node shows the reason on its body with a red frame. - Nodes: `Texture color`, `Output` (one per graph), `Property`, `Color`, `Add`/`Subtract`/`Multiply`/`Divide`, `Mix`, `Luminance`. Values are `number` (float) or `vec3` (colour); math ports are `any` (a colour on either side makes the result a colour, a float is broadcast). - Compiler `core/shader/compile.ts`: one GLSL local per reachable node, `uniform float u_<name>` per Property, unpremultiply in the prelude, clamp and re-multiply in the epilogue. Fatal problems shown at the node: no Output, invalid/duplicate property name, cycle, colour into a number port. - Sprite rows come from the asset, so `schemaForAsset`, `schemaForObject`, `resolveAssetProps`, `resolveSceneObjectProps`, `isModified`, `deviatesFromAsset`, `requirePropDef` and friends now take the project (43 call sites). Override/Reset/Apply, gold marks and the `Properties` node work per property key; a value without a visible row stays stored but marks nothing. - "Adjust colors" is a graph of 11 nodes (`tools/lib/shaders.mjs`), shipped in the fixture and the three example games. **Proof:** `./check.sh` 850 tests, e2e step 28 (new) 29 checks, neighbouring modules 2/4/6/24/26 187 checks, Jump-Run/Tetris/Actor 24/19/20, bundle byte-identical after a rebuild. Pixels on `#4080ff`: brightness 0.5 `#204080`, contrast 0 `#808080`, saturation 0 `#7c7c7c`, all byte-exact; a red `Color` node hung into the Output recolours the sprite live. The full run is CI's after the push. **Not in this step:** alpha input on Output, more nodes, a preview sprite in the tab, text objects. Follow-up (user, after looking at the Actor graph): brightness should work by **Add**, not Multiply, with all values at 1 still leaving the pixel untouched.
Owner

Follow-up, on request: brightness adds instead of multiplying.

The shipped Adjust colors graph gained a brightness - 1 offset node feeding the Add, so 1 stays neutral and brightness lifts every channel by the same amount; contrast keeps multiplying around 0.5, saturation keeps mixing with the luma. Fixture, the three game seeds and the expectations follow (twelve nodes; brightness 1.25 on #4080ff gives #80c0ff, measured at the pixel).

  • Code: a32b7c6
  • Wiki Shaders: 349d543
  • Gate 850 tests, module 28 ALL PASSED - 29 checks
Follow-up, on request: **brightness adds instead of multiplying.** The shipped *Adjust colors* graph gained a `brightness - 1` offset node feeding the `Add`, so 1 stays neutral and brightness lifts every channel by the same amount; contrast keeps multiplying around 0.5, saturation keeps mixing with the luma. Fixture, the three game seeds and the expectations follow (twelve nodes; brightness 1.25 on `#4080ff` gives `#80c0ff`, measured at the pixel). - Code: `a32b7c6` - Wiki *Shaders*: `349d543` - Gate 850 tests, module 28 `ALL PASSED - 29 checks`
admin added this to the Development project 2026-09-13 13:43:19 +02:00
admin moved this to Done in Development on 2026-09-13 13:44:15 +02:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#62