Shaders: the preview next to the graph (#168)

- Shaders: new section "The preview" with what each selection shows
- Architecture: ShaderPreview, previewPicture and PreviewSplit
- Development: check total 1209

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
adminandClaude Opus 5 committed 2026-09-21 08:55:02 +02:00
1 parent 3d5f892afb
commit 41b1532a33
3 files changed
+39 -1

No files matched your search

+5
@@ -179,6 +179,11 @@ src/editor/tile/ TileEditor (header + kind), TileCanvas (every tile of th
src/editor/statemachine/ StateMachineEditor (header, on the graph canvas)
src/editor/particles/ ParticlesEditor (graph canvas left of a preview panel, splitter between them),
ParticlePreview (the panel: the asset's own particles, wearing its own rows)
src/editor/shader/ ShaderEditor (graph canvas, preview panel with a slider per property, #168),
ShaderPreview (one sprite mesh wearing the shader through syncShader, own clock),
previewPicture (which selection has a picture, what it shows, slider start values,
the built-in test image)
src/editor/PreviewSplit.ts graph left, preview panel right, the splitter between them (Particles, Shader)
src/editor/list/ ListEditor (a row per item), slot (which list is being edited, and how it is written back)
src/editor/console/ log (ring buffer, argument formatting, the console.* capture), ConsolePanel (the tail under the tabs)
api/ PHP backend: index.php (routing and the sign-in gate),
+1 -1
@@ -13,7 +13,7 @@ npm run check # typecheck + lint + format:check + tests, the gate CI runs
npm run build # writes dist/ and regenerates index.html
./build.sh # the same under `set -o pipefail`, for callers that pipe the output
php tools/make-user.php <name> <password> # an account; every tool signs in (see Accounts)
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1202 editor checks, screenshots in /tmp/gm-e2e-*.png
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1209 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result
+33
@@ -17,6 +17,39 @@ and a red frame.
A shader graph is compiled on every change. A sprite wearing a graph that does not compile is drawn
plain, as if it wore none.
### The preview
Right of the graph, behind a splitter you can drag like the one in the Particles tab, the tab shows
one picture wearing the shader. The picture is **whatever you selected last that has one**:
| Selected last | The preview shows |
|---|---|
| a placed sprite | that sprite, with its overrides: its picture, its width and height, its colour |
| a sprite asset | the sprite as the asset describes it |
| a texture | the whole sheet |
| a frame (Texture tab) | that frame |
| nothing of the above yet | a built-in **test image** |
Selecting the shader itself, one of its nodes or anything without a picture (a behavior, a scene)
keeps the picture that is there. The line below the buttons names it. The picture is looked up again
on every change, so an edit in the inspector shows at once. Once it is deleted, the test image comes
back. The test image is 64 pixels square: colour runs from left to right and from top to bottom, a
checker of 8-pixel cells shows where a UV lands, and the outer 8 pixels fade out so an alpha effect
has something to work on.
Below the picture there is **a slider for every property** the shader declares. The sliders belong
to the preview: moving one never writes into the project, not into the sprite and not into the
Property node. They start at the sprite's own values when the picture is a sprite that already wears
this shader, otherwise at the property's default. They reach from the property's `min` to its `max`.
A property without a `max` gets twice its default's distance from the `min`.
A shader with a **Time** node runs on the preview's own clock. `Hold` stops it at the second it shows
(the button then reads `Run`), `Restart` goes back to 0. Without a Time node both buttons are greyed
out, because nothing in the picture moves.
The preview draws the picture unsliced, even a nine-sliced frame: it is about what the shader does to
the pixels, not about how a sprite stretches.
## The nodes
Every value is either a **number** (a GLSL `float`) or a **colour** (a `vec3`, RGB in 0-1). Ports