Shader Output Standardwert ändern auf "Clamp" #81

Closed
opened 2026-09-13 18:53:36 +02:00 by admin · 1 comment

Wie der Titel schon beschreibt + kurze Frage: was ist der standardwert wenn man keinen shader zuweist

Wie der Titel schon beschreibt + kurze Frage: was ist der standardwert wenn man keinen shader zuweist
admin added this to the Development project 2026-09-13 18:53:36 +02:00
admin moved this to Next in Development on 2026-09-13 18:53:41 +02:00
Owner

Erledigt in e0c459c, Wiki 7ed7bc8.

Deine Frage zuerst: was gilt ohne Shader?

Faktisch Clamp — und genau deshalb ist Clamp jetzt auch die Vorgabe.

Ohne Shader stellt sich die Frage nie: die Koordinaten des Sprite-Quads laufen exakt 0..1 und verlassen das Bild nicht. Die geteilte Textur trägt technisch mirror-repeat, und das liest innerhalb eines Texels wie clamp (der gespiegelte Nachbar am Rand ist der Randtexel). Ein Sprite ohne Shader sieht also aus, als wäre der Rand geklemmt. Vorher stand am Output trotzdem Mirror — der eine Fall, in dem die Vorgabe von dem abwich, was man ohne sie sieht.

Was es kostete, dass das kein Einzeiler war

DEFAULT_EDGE hatte zwei Aufgaben in einer Konstante: die Vorgabe am Output-Node und den Sentinel „das ist der Modus, den die geteilte Basistextur ohnehin hat, dafür braucht es keine eigene Textur". Den Wert einfach auf clamp zu setzen hätte die Sentinel-Vergleiche in TextureLibrary.get/crop und in symbols.ts mitgedreht — und jedem Shader-Sprite eine Vollkopie seiner Textur verpasst, auch einem reinen Brightness-Shader, bei dem der Randmodus gar nichts tun kann.

Getrennt:

SHEET_EDGE = 'mirror' was die Basistextur physisch trägt; der Fall „Sprite ohne Shader" und „keine eigene Variante nötig"
DEFAULT_EDGE = 'clamp' nur die Vorgabe am Output-Node

Dazu: CompiledShader.edge meldet jetzt die nötige Textur-Variante, nicht den Param. Ohne einen Sample texture, dessen u oder v per Kante gefüttert ist, kann kein Randmodus sichtbar werden — dann bleibt es beim schlichten Sheet. Der häufige Shader kostet damit keine zweite Kopie des Bildes, auch nicht mit Repeat am Output.

Das Sheet selbst kann clamp-to-edge übrigens nicht tragen: Pixi biegt das auf jeder Textur, die ein Graphics-Fill zeichnet, zu repeat um (generateTextureFillMatrix). Clamp ist deshalb immer ein eigener Schnitt.

Bestehende Graphen

Gemessen statt vermutet: auf dem Server trägt kein einziger Output-Node explizit mirror (data/projects/*.json durchsucht). Graphen aus der Zeit vor der Einstellung haben gar keinen Wert und folgen der Vorgabe — sie wechseln also mit, und das ist gewollt. Ein neuer Output-Node schreibt clamp in den Graphen, so wie jeder andere Param-Default auch. Eine Migration war damit weder nötig noch sinnvoll (sie könnte „nie angefasst" nicht von „bewusst Mirror gewählt" unterscheiden).

Messfalle, die mich fast einen wertlosen Check gekostet hätte

Der bestehende Scroll-Check u + 0.5 unterscheidet Clamp nicht von Mirror: bei 1.3 hält Mirror (→ 0.7) dieselbe ferne Hälfte wie Clamp (→ 1.0). Ein Check darauf wäre unter beiden Vorgaben grün geblieben. Erst u + 0.8 trennt sie: 1.6 → Clamp hält den Randtexel (grün), Mirror ist schon zurück in der nahen Hälfte (rot). Der neue Check misst beide Seiten im selben Lauf.

Geprüft, nicht behauptet

./check.sh === CHECK EXIT 0 ===, 887 Tests, Log jünger als jede Quelle
e2e Modul 28 ALL PASSED – 56 Checks (+1), gegen index-DPZFWE1k.js
Pixel ohne Einstellung am Output: rechts #3cc85a (grün, Clamp); mit Mirror: #e63c3c (rot)
Sauberkeit keine Sonden im Diff, nichts in src/tests/tools jünger als das Log

Zwei Gegenproben, jede beißt an ihrer Stelle:

  • Vorgabe zurück auf mirror, neu gebaut → genau 1 FAILED von 56, mit {"byDefault":"#e63c3c"} — rot statt grün, exakt der Unterschied. Rückbau → Neubau ergibt wieder index-DPZFWE1k.js, denselben Inhalts-Hash wie das Bundle des grünen Laufs.
  • Varianten-Regel stumpf (immer der Param statt des Sheets) → genau die zwei Unit-Stellen fallen, die den Sheet-Fall festnageln; die übrigen 20 im Modul bleiben grün.

Was ich nicht angesehen habe

Das Edge-Dropdown selbst im Inspector (neue Reihenfolge: Clamp, Mirror, Repeat). Der Screenshot des Laufs zeigt den Graphen, nicht das Feld. Belegt ist die Vorgabe über das Modell (ein frisch angelegter Output-Node trägt clamp) und über den gemessenen Pixel — nicht durch Hinsehen.

Wiki Shaders: Node-Tabelle, das Scroll-Rezept, die Antwort auf deine Frage im Abschnitt über die Grenzen, und „In the code" mit der Varianten-Regel und dem Pixi-Zwang. Zähler 785 (CI-Lauf 32 hat 784 gemessen, plus mein einer neuer Check).

Erledigt in `e0c459c`, Wiki `7ed7bc8`. ## Deine Frage zuerst: was gilt ohne Shader? **Faktisch Clamp** — und genau deshalb ist Clamp jetzt auch die Vorgabe. Ohne Shader stellt sich die Frage nie: die Koordinaten des Sprite-Quads laufen exakt 0..1 und verlassen das Bild nicht. Die geteilte Textur trägt technisch `mirror-repeat`, und das liest **innerhalb eines Texels wie clamp** (der gespiegelte Nachbar am Rand *ist* der Randtexel). Ein Sprite ohne Shader sieht also aus, als wäre der Rand geklemmt. Vorher stand am Output trotzdem *Mirror* — der eine Fall, in dem die Vorgabe von dem abwich, was man ohne sie sieht. ## Was es kostete, dass das kein Einzeiler war `DEFAULT_EDGE` hatte **zwei Aufgaben in einer Konstante**: die Vorgabe am Output-Node *und* den Sentinel „das ist der Modus, den die geteilte Basistextur ohnehin hat, dafür braucht es keine eigene Textur". Den Wert einfach auf `clamp` zu setzen hätte die Sentinel-Vergleiche in `TextureLibrary.get`/`crop` und in `symbols.ts` mitgedreht — und **jedem** Shader-Sprite eine Vollkopie seiner Textur verpasst, auch einem reinen Brightness-Shader, bei dem der Randmodus gar nichts tun kann. Getrennt: | | | |---|---| | **`SHEET_EDGE = 'mirror'`** | was die Basistextur physisch trägt; der Fall „Sprite ohne Shader" und „keine eigene Variante nötig" | | **`DEFAULT_EDGE = 'clamp'`** | nur die Vorgabe am Output-Node | Dazu: **`CompiledShader.edge` meldet jetzt die nötige Textur-Variante, nicht den Param.** Ohne einen `Sample texture`, dessen `u` oder `v` per Kante gefüttert ist, kann kein Randmodus sichtbar werden — dann bleibt es beim schlichten Sheet. Der häufige Shader kostet damit keine zweite Kopie des Bildes, auch nicht mit *Repeat* am Output. Das Sheet selbst kann `clamp-to-edge` übrigens **nicht** tragen: Pixi biegt das auf jeder Textur, die ein Graphics-Fill zeichnet, zu `repeat` um (`generateTextureFillMatrix`). Clamp ist deshalb immer ein eigener Schnitt. ## Bestehende Graphen Gemessen statt vermutet: auf dem Server trägt **kein einziger** Output-Node explizit `mirror` (`data/projects/*.json` durchsucht). Graphen aus der Zeit vor der Einstellung haben gar keinen Wert und folgen der Vorgabe — sie wechseln also mit, und das ist gewollt. Ein *neuer* Output-Node schreibt `clamp` in den Graphen, so wie jeder andere Param-Default auch. Eine Migration war damit weder nötig noch sinnvoll (sie könnte „nie angefasst" nicht von „bewusst Mirror gewählt" unterscheiden). ## Messfalle, die mich fast einen wertlosen Check gekostet hätte Der bestehende Scroll-Check `u + 0.5` unterscheidet Clamp **nicht** von Mirror: bei 1.3 hält Mirror (→ 0.7) dieselbe ferne Hälfte wie Clamp (→ 1.0). Ein Check darauf wäre unter beiden Vorgaben grün geblieben. Erst **`u + 0.8`** trennt sie: 1.6 → Clamp hält den Randtexel (grün), Mirror ist schon zurück in der nahen Hälfte (rot). Der neue Check misst beide Seiten im selben Lauf. ## Geprüft, nicht behauptet | | | |---|---| | `./check.sh` | `=== CHECK EXIT 0 ===`, **887 Tests**, Log jünger als jede Quelle | | e2e Modul 28 | **ALL PASSED – 56 Checks** (+1), gegen `index-DPZFWE1k.js` | | Pixel | ohne Einstellung am Output: rechts `#3cc85a` (grün, Clamp); mit *Mirror*: `#e63c3c` (rot) | | Sauberkeit | keine Sonden im Diff, nichts in `src`/`tests`/`tools` jünger als das Log | **Zwei Gegenproben, jede beißt an ihrer Stelle:** - **Vorgabe zurück auf `mirror`**, neu gebaut → **genau 1 FAILED** von 56, mit `{"byDefault":"#e63c3c"}` — rot statt grün, exakt der Unterschied. Rückbau → Neubau ergibt wieder **`index-DPZFWE1k.js`**, denselben Inhalts-Hash wie das Bundle des grünen Laufs. - **Varianten-Regel stumpf** (immer der Param statt des Sheets) → genau die zwei Unit-Stellen fallen, die den Sheet-Fall festnageln; die übrigen 20 im Modul bleiben grün. ## Was ich *nicht* angesehen habe Das Edge-Dropdown selbst im Inspector (neue Reihenfolge: Clamp, Mirror, Repeat). Der Screenshot des Laufs zeigt den Graphen, nicht das Feld. Belegt ist die Vorgabe über das Modell (ein frisch angelegter Output-Node trägt `clamp`) und über den gemessenen Pixel — nicht durch Hinsehen. Wiki *Shaders*: Node-Tabelle, das Scroll-Rezept, die Antwort auf deine Frage im Abschnitt über die Grenzen, und „In the code" mit der Varianten-Regel und dem Pixi-Zwang. Zähler **785** (CI-Lauf 32 hat 784 gemessen, plus mein einer neuer Check).
admin moved this to Done in Development on 2026-09-13 21:36:53 +02:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#81