Folge-Issue aus #300 (Entscheidung des Users 2026-10-03: Radius des Blur höchstens 8, mehrere Passes als eigenes Issue).
Befund
Seit #300 zeichnet der Node Blur in einem Pass weich, bis Radius 8. Bei Direction Both sind das bis zu 289 Samples je Pixel.
Breiter wird ein Pass schnell teuer, weil die Samples mit (2r+1)² wachsen. Zwei Passes (erst horizontal, dann vertikal) brauchen nur 2·(2r+1): bei Radius 16 sind das 66 statt 1089.
Bloom geht in einem Pass gar nicht: helle Stellen herausziehen, breit weichzeichnen und wieder auf das Bild addieren. Dafür muss das Ergebnis eines Passes im nächsten als Bild lesbar sein.
Den Weg „in ein Bild zeichnen, Shader darüber“ gibt es seit #170 (Feld-Shader: RenderTexture plus Mesh). Die Kamera (#299) wird ihn auch nutzen.
Zu klären
Form: mehrere Shader an einer Zeile (jeder liest das Bild des vorigen), mehrere Output-Nodes in einem Shader-Asset (Pass 1, Pass 2 …) oder ein Node Previous pass?
Das Ursprungsbild in späteren Passes: Bloom braucht das Original und das Weichgezeichnete zugleich.
Auflösung der Zwischenbilder: voll oder halb? Halb ist beim Blur der übliche Trick und viertelt die Kosten.
Träger: überall, wo ein Shader läuft (Sprite, Text, Partikel, Feld, Kamera), oder vorerst nur Feld und Kamera, die ohnehin schon in ein Bild zeichnen?
Rand: Ein Blur braucht Padding. Wie wächst der Rand über mehrere Passes?
Beweis beim Schließen
Ein Blur in zwei Passes (horizontal, dann vertikal) zeichnet bis auf Rundung dasselbe wie Blur mit Direction Both bei gleichem Radius.
Messung wie in #67 und #170: Bilder je Sekunde für einen und zwei Passes bei Radius 4, 8 und 16.
Ein Bloom-Rezept steht im Wiki.
Folge-Issue aus #300 (Entscheidung des Users 2026-10-03: Radius des `Blur` höchstens 8, mehrere Passes als eigenes Issue).
## Befund
- Seit #300 zeichnet der Node `Blur` in **einem** Pass weich, bis Radius 8. Bei *Direction* Both sind das bis zu 289 Samples je Pixel.
- Breiter wird ein Pass schnell teuer, weil die Samples mit (2r+1)² wachsen. Zwei Passes (erst horizontal, dann vertikal) brauchen nur 2·(2r+1): bei Radius 16 sind das 66 statt 1089.
- **Bloom geht in einem Pass gar nicht:** helle Stellen herausziehen, breit weichzeichnen und wieder auf das Bild addieren. Dafür muss das Ergebnis eines Passes im nächsten als Bild lesbar sein.
- Den Weg „in ein Bild zeichnen, Shader darüber“ gibt es seit #170 (Feld-Shader: RenderTexture plus Mesh). Die Kamera (#299) wird ihn auch nutzen.
## Zu klären
1. **Form:** mehrere Shader an einer Zeile (jeder liest das Bild des vorigen), mehrere `Output`-Nodes in einem Shader-Asset (Pass 1, Pass 2 …) oder ein Node `Previous pass`?
2. **Das Ursprungsbild in späteren Passes:** Bloom braucht das Original und das Weichgezeichnete zugleich.
3. **Auflösung der Zwischenbilder:** voll oder halb? Halb ist beim Blur der übliche Trick und viertelt die Kosten.
4. **Träger:** überall, wo ein Shader läuft (Sprite, Text, Partikel, Feld, Kamera), oder vorerst nur Feld und Kamera, die ohnehin schon in ein Bild zeichnen?
5. **Rand:** Ein Blur braucht `Padding`. Wie wächst der Rand über mehrere Passes?
## Beweis beim Schließen
- Ein Blur in zwei Passes (horizontal, dann vertikal) zeichnet bis auf Rundung dasselbe wie `Blur` mit *Direction* Both bei gleichem Radius.
- Messung wie in #67 und #170: Bilder je Sekunde für einen und zwei Passes bei Radius 4, 8 und 16.
- Ein Bloom-Rezept steht im Wiki.
meleki
added the shader label 2026-10-03 12:48:00 +02:00
soll im graph irgendwo definierbar sein - bitte um vorschlag!
bitte überall
padding stellt man selbst ein, man sieht in der vorschau das ergebnis, was brauchst du da genau für eine abklärung?
1. was wäre eleganter? schlag du vor.
2. hier ebenfalls, schlage etwas vor.
3. soll im graph irgendwo definierbar sein - bitte um vorschlag!
4. bitte überall
5. padding stellt man selbst ein, man sieht in der vorschau das ergebnis, was brauchst du da genau für eine abklärung?
admin
added this to the Development project 2026-10-03 13:23:17 +02:00
admin
moved this to Next in Development on 2026-10-03 13:23:27 +02:00
admin
moved this to Done in Development on 2026-10-03 14:51:05 +02:00
Umgesetzt in f03ca0d, Wiki d36fc4a (Shaders: Node-Tabelle, Abschnitt Drawing in passes mit Bloom-Rezept und Rezept für Radius 16, Messtabellen; Particles: ein Pixel im Feld-Shader ist eine Einheit des Rahmens; Development: Summe).
Entscheidungen (Kommentar 3034 und zwei Auswahlfragen)
Form: Node Pass als Schnitt im Graph. Eingänge color/alpha wie am Output, Setting Resolution (Full/Half/Quarter), Ausgang picture.
Ursprungsbild: Die Bild-Nodes (Texture color, Texture alpha, Sample texture, Blur, Texture size) haben einen Eingang picture. Offen lesen sie wie bisher das Original, das damit neben jedem Pass verfügbar bleibt.
Auflösung:Resolution am Pass-Node.
Träger: überall. Sprite (9-Slice über das ungeschnittene Bild), Text, Partikelquelle, Feld-Shader und die Vorschau im Shader-Tab.
Rand: Jedes Zwischenbild ist Bild plus Padding vom Output. Padding stellt man einmal ein.
Tönung: Zwischenpasses sehen das Bild ungetönt. Die Tönung wirkt erst, wenn der letzte Teil ein Bild liest. An einer Partikelquelle laufen die Passes deshalb einmal für alle Partikel.
Was ich selbst festgelegt habe
picture ist ein eigener Porttyp und passt nur auf picture, auch nicht auf any.
Höchstens 8 Passes je Graph, höchstens 2048 Pixel je Seite. Ein Pass, der sein eigenes Bild liest, meldet Feeds itself. Ein Pass kann den Vertex output nicht speisen.
Ein Zwischenbild wird mit dem Filter des Bildes gelesen (Nearest bleibt scharf) und geht über seinen Rahmen hinaus so weiter, wie Edge am Output sagt.
Texture size an einem Pass-Bild zählt das Padding mit.
Gezeichnet wird ein Pass nur neu, wenn sich Bild, Größe, Padding oder ein Uniform ändert. Ein ruhendes Sprite zeichnet seine Passes einmal, mit Time im Graph jeden Frame. Das Feldbild ist jeden Frame neu, also auch seine Passes.
Ein Blur zählt seinen Radius in Pixeln des Bildes, das er liest. Für Radius 16 kommt deshalb zuerst ein offener Pass auf Half, dann BlurHorizontal (8) auf dessen Bild, ein zweiter Pass auf Half und BlurVertical (8). Quarter reicht 32. Das Rezept steht im Wiki.
Nachgezogen (aus deinen Screenshots)
Feld-Shader hängt nicht mehr vom Zoom ab (deine Wahl: Option 1). Im Feld-Shader zählt ein Pixel als Einheit des Rahmens, nicht als Bildschirmpixel. Blur und Texture size rechnen damit (Uniform uPixelScale), Texture size liefert also Field width × Field height. Das Feldbild bleibt in Bildschirmpixeln scharf. Der Fehler stammte aus #170/#300, betraf mit den Passes aber auch #301.
Weißes Bild beim ersten Anzeigen behoben. Pixi baut den Code, der die Ressourcen eines Programms bindet, nur einmal je Programm und greift danach per Position zu. Ein Pass aus einem Graph mit weniger Passes hatte denselben Quelltext wie Pass 0 in deinem Graph, aber weniger Plätze. Der zweite Graph hat dann den weißen Platzhalter gelesen. Jetzt hat jeder Shader immer alle 8 Plätze und seine Uniform-Gruppe. F5 hat nur geholfen, weil danach dein Graph als Erster gezeichnet wurde.
Beweise
Zwei Passes = Both: Ein weißes Pixel, horizontal mit Radius 2 geweichzeichnet, dann Pass, dann vertikal, ergibt denselben 5x5-Fleck wie ein BlurBoth (25 x 0,04, Abstand 0,000, e2e 28l-vii).
Original neben Pass, einmal getönt: Graues Sprite, Pass-Bild plus Original im roten Teil: 231/60/60 (gerechnet 230/60/60).
Gegenproben: Ein getönter Pass lässt 1 Unit-Test fallen. Werden die Bilder nicht gebunden, fallen beide e2e-Checks (Fleck 0,20 statt 0,04, Bloom 243/158/158).
Messung (stein2, HD 630, ein Lauf je Zeile, fps; auf Sprites hängt der Radius an Time, damit der Pass jeden Frame neu gezeichnet wird):
Sprites 48x48
100
400
800
Radius 4, ein Pass
53,1
50,7
35,5
Radius 8, ein Pass
49,4
24,2
13,9
Radius 4, zwei Passes
59,1
45,6
24,1
Radius 8, zwei Passes
56,2
46,0
24,5
Radius 16, drei Passes auf Half
51,5
27,1
14,2
Feld-Shader 256x256
1
10
50
Radius 4, ein Pass
59,0
49,7
27,2
Radius 8, ein Pass
54,5
35,0
11,4
Radius 4, zwei Passes
60,0
55,1
49,2
Radius 8, zwei Passes
59,9
51,3
41,3
Radius 16, drei Passes auf Half
59,9
55,6
44,4
Radius 16 heißt: offener Pass auf Half, dann die zwei Blur-Passes auf Half, also drei Durchgänge. Die erste Messung dieser Zeile war falsch, weil der offene Pass vorne fehlte.
Am großen Bild lohnen sich zwei Passes deutlich. Bei kleinen Sprites kostet der Wechsel des Zeichenziels mehr, als die Samples sparen: Bei Radius 4 ist ein Pass ab 400 Sprites schneller, und Radius 16 ist bei 800 Sprites so langsam wie Radius 8 in einem Pass.
e2e 28 und 31 (melektaus-atx): 97 Checks (94 + 3) und 44 Checks (43 + 1), alle grün, keine Pixi-Warnung.
Neu: zwei Passes hintereinander nach einem Graph mit einem Pass zeigen Rot und Grün statt Weiß (28l-vii). Ein Blur 8 lässt den Rahmenrand eines Feldes bei 50 % und bei 200 % über 8,0 Einheiten auslaufen (31v-iii).
Gegenproben dazu: Pass-Plätze nach der Zahl der Passes → #ffffff. Feld ohne Pixel-Maßstab → 16 bzw. 4 Einheiten. Es fallen genau die zwei neuen Checks.
e2e-Summe 1716 ist gerechnet (1712 + 4).
Nicht im Browser geprüft: das Bloom-Rezept selbst, Half/Quarter als Bild, Passes an Text, 9-Slice und Partikeln, am Feld lief nur die Messung, sowie die Vorschau im Shader-Tab.
Umgesetzt in f03ca0d, Wiki d36fc4a (*Shaders*: Node-Tabelle, Abschnitt *Drawing in passes* mit Bloom-Rezept und Rezept für Radius 16, Messtabellen; *Particles*: ein Pixel im Feld-Shader ist eine Einheit des Rahmens; *Development*: Summe).
## Entscheidungen (Kommentar 3034 und zwei Auswahlfragen)
1. **Form:** Node `Pass` als Schnitt im Graph. Eingänge `color`/`alpha` wie am Output, Setting *Resolution* (Full/Half/Quarter), Ausgang `picture`.
2. **Ursprungsbild:** Die Bild-Nodes (`Texture color`, `Texture alpha`, `Sample texture`, `Blur`, `Texture size`) haben einen Eingang `picture`. Offen lesen sie wie bisher das Original, das damit neben jedem Pass verfügbar bleibt.
3. **Auflösung:** *Resolution* am Pass-Node.
4. **Träger:** überall. Sprite (9-Slice über das ungeschnittene Bild), Text, Partikelquelle, Feld-Shader und die Vorschau im Shader-Tab.
5. **Rand:** Jedes Zwischenbild ist Bild plus Padding vom Output. Padding stellt man einmal ein.
- **Tönung:** Zwischenpasses sehen das Bild ungetönt. Die Tönung wirkt erst, wenn der letzte Teil ein Bild liest. An einer Partikelquelle laufen die Passes deshalb einmal für alle Partikel.
## Was ich selbst festgelegt habe
- `picture` ist ein eigener Porttyp und passt nur auf `picture`, auch nicht auf `any`.
- Höchstens 8 Passes je Graph, höchstens 2048 Pixel je Seite. Ein Pass, der sein eigenes Bild liest, meldet *Feeds itself*. Ein Pass kann den `Vertex output` nicht speisen.
- Ein Zwischenbild wird mit dem Filter des Bildes gelesen (*Nearest* bleibt scharf) und geht über seinen Rahmen hinaus so weiter, wie *Edge* am Output sagt.
- `Texture size` an einem Pass-Bild zählt das Padding mit.
- Gezeichnet wird ein Pass nur neu, wenn sich Bild, Größe, Padding oder ein Uniform ändert. Ein ruhendes Sprite zeichnet seine Passes einmal, mit `Time` im Graph jeden Frame. Das Feldbild ist jeden Frame neu, also auch seine Passes.
- Ein Blur zählt seinen Radius in Pixeln des Bildes, das er liest. Für Radius 16 kommt deshalb zuerst ein offener Pass auf *Half*, dann `Blur` *Horizontal* (8) auf dessen Bild, ein zweiter Pass auf *Half* und `Blur` *Vertical* (8). *Quarter* reicht 32. Das Rezept steht im Wiki.
## Nachgezogen (aus deinen Screenshots)
- **Feld-Shader hängt nicht mehr vom Zoom ab** (deine Wahl: Option 1). Im Feld-Shader zählt ein Pixel als Einheit des Rahmens, nicht als Bildschirmpixel. `Blur` und `Texture size` rechnen damit (Uniform `uPixelScale`), `Texture size` liefert also *Field width* × *Field height*. Das Feldbild bleibt in Bildschirmpixeln scharf. Der Fehler stammte aus #170/#300, betraf mit den Passes aber auch #301.
- **Weißes Bild beim ersten Anzeigen behoben.** Pixi baut den Code, der die Ressourcen eines Programms bindet, nur einmal je Programm und greift danach per Position zu. Ein Pass aus einem Graph mit weniger Passes hatte denselben Quelltext wie Pass 0 in deinem Graph, aber weniger Plätze. Der zweite Graph hat dann den weißen Platzhalter gelesen. Jetzt hat jeder Shader immer alle 8 Plätze und seine Uniform-Gruppe. F5 hat nur geholfen, weil danach dein Graph als Erster gezeichnet wurde.
## Beweise
- **Zwei Passes = Both:** Ein weißes Pixel, horizontal mit Radius 2 geweichzeichnet, dann `Pass`, dann vertikal, ergibt denselben 5x5-Fleck wie ein `Blur` *Both* (25 x 0,04, Abstand 0,000, e2e 28l-vii).
- **Original neben Pass, einmal getönt:** Graues Sprite, Pass-Bild plus Original im roten Teil: 231/60/60 (gerechnet 230/60/60).
- **Gegenproben:** Ein getönter Pass lässt 1 Unit-Test fallen. Werden die Bilder nicht gebunden, fallen beide e2e-Checks (Fleck 0,20 statt 0,04, Bloom 243/158/158).
- **Messung** (stein2, HD 630, ein Lauf je Zeile, fps; auf Sprites hängt der Radius an `Time`, damit der Pass jeden Frame neu gezeichnet wird):
| Sprites 48x48 | 100 | 400 | 800 |
|---|---|---|---|
| Radius 4, ein Pass | 53,1 | 50,7 | 35,5 |
| Radius 8, ein Pass | 49,4 | 24,2 | 13,9 |
| Radius 4, zwei Passes | 59,1 | 45,6 | 24,1 |
| Radius 8, zwei Passes | 56,2 | 46,0 | 24,5 |
| Radius 16, drei Passes auf Half | 51,5 | 27,1 | 14,2 |
| Feld-Shader 256x256 | 1 | 10 | 50 |
|---|---|---|---|
| Radius 4, ein Pass | 59,0 | 49,7 | 27,2 |
| Radius 8, ein Pass | 54,5 | 35,0 | 11,4 |
| Radius 4, zwei Passes | 60,0 | 55,1 | 49,2 |
| Radius 8, zwei Passes | 59,9 | 51,3 | 41,3 |
| Radius 16, drei Passes auf Half | 59,9 | 55,6 | 44,4 |
Radius 16 heißt: offener Pass auf *Half*, dann die zwei Blur-Passes auf *Half*, also drei Durchgänge. Die erste Messung dieser Zeile war falsch, weil der offene Pass vorne fehlte.
Am großen Bild lohnen sich zwei Passes deutlich. Bei kleinen Sprites kostet der Wechsel des Zeichenziels mehr, als die Samples sparen: Bei Radius 4 ist ein Pass ab 400 Sprites schneller, und Radius 16 ist bei 800 Sprites so langsam wie Radius 8 in einem Pass.
- **Bloom-Rezept** steht im Wiki (*Drawing in passes*).
## Tests
- Gate (melektaus-atx): 225 Files, 3480 Tests (3467 + 13), `CHECK EXIT 0`.
- e2e 28 und 31 (melektaus-atx): 97 Checks (94 + 3) und 44 Checks (43 + 1), alle grün, keine Pixi-Warnung.
- Neu: zwei Passes hintereinander nach einem Graph mit einem Pass zeigen Rot und Grün statt Weiß (28l-vii). Ein Blur 8 lässt den Rahmenrand eines Feldes bei 50 % und bei 200 % über 8,0 Einheiten auslaufen (31v-iii).
- Gegenproben dazu: Pass-Plätze nach der Zahl der Passes → `#ffffff`. Feld ohne Pixel-Maßstab → 16 bzw. 4 Einheiten. Es fallen genau die zwei neuen Checks.
- e2e-Summe 1716 ist gerechnet (1712 + 4).
**Nicht im Browser geprüft:** das Bloom-Rezept selbst, *Half*/*Quarter* als Bild, Passes an Text, 9-Slice und Partikeln, am Feld lief nur die Messung, sowie die Vorschau im Shader-Tab.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Folge-Issue aus #300 (Entscheidung des Users 2026-10-03: Radius des
Blurhöchstens 8, mehrere Passes als eigenes Issue).Befund
Blurin einem Pass weich, bis Radius 8. Bei Direction Both sind das bis zu 289 Samples je Pixel.Zu klären
Output-Nodes in einem Shader-Asset (Pass 1, Pass 2 …) oder ein NodePrevious pass?Padding. Wie wächst der Rand über mehrere Passes?Beweis beim Schließen
Blurmit Direction Both bei gleichem Radius.Umgesetzt in
f03ca0d, Wiki d36fc4a (Shaders: Node-Tabelle, Abschnitt Drawing in passes mit Bloom-Rezept und Rezept für Radius 16, Messtabellen; Particles: ein Pixel im Feld-Shader ist eine Einheit des Rahmens; Development: Summe).Entscheidungen (Kommentar 3034 und zwei Auswahlfragen)
Passals Schnitt im Graph. Eingängecolor/alphawie am Output, Setting Resolution (Full/Half/Quarter), Ausgangpicture.Texture color,Texture alpha,Sample texture,Blur,Texture size) haben einen Eingangpicture. Offen lesen sie wie bisher das Original, das damit neben jedem Pass verfügbar bleibt.Was ich selbst festgelegt habe
pictureist ein eigener Porttyp und passt nur aufpicture, auch nicht aufany.Vertex outputnicht speisen.Texture sizean einem Pass-Bild zählt das Padding mit.Timeim Graph jeden Frame. Das Feldbild ist jeden Frame neu, also auch seine Passes.BlurHorizontal (8) auf dessen Bild, ein zweiter Pass auf Half undBlurVertical (8). Quarter reicht 32. Das Rezept steht im Wiki.Nachgezogen (aus deinen Screenshots)
BlurundTexture sizerechnen damit (UniformuPixelScale),Texture sizeliefert also Field width × Field height. Das Feldbild bleibt in Bildschirmpixeln scharf. Der Fehler stammte aus #170/#300, betraf mit den Passes aber auch #301.Beweise
Pass, dann vertikal, ergibt denselben 5x5-Fleck wie einBlurBoth (25 x 0,04, Abstand 0,000, e2e 28l-vii).Time, damit der Pass jeden Frame neu gezeichnet wird):Radius 16 heißt: offener Pass auf Half, dann die zwei Blur-Passes auf Half, also drei Durchgänge. Die erste Messung dieser Zeile war falsch, weil der offene Pass vorne fehlte.
Am großen Bild lohnen sich zwei Passes deutlich. Bei kleinen Sprites kostet der Wechsel des Zeichenziels mehr, als die Samples sparen: Bei Radius 4 ist ein Pass ab 400 Sprites schneller, und Radius 16 ist bei 800 Sprites so langsam wie Radius 8 in einem Pass.
Tests
CHECK EXIT 0.#ffffff. Feld ohne Pixel-Maßstab → 16 bzw. 4 Einheiten. Es fallen genau die zwei neuen Checks.Nicht im Browser geprüft: das Bloom-Rezept selbst, Half/Quarter als Bild, Passes an Text, 9-Slice und Partikeln, am Feld lief nur die Messung, sowie die Vorschau im Shader-Tab.