Bildweite Effekte gehören nicht in den Szenen-Shader. Cel-Ramp und Sobel-Outline sollen dazukommen, ohne einander (oder scene.wgsl) zu kennen — also eine Kette gleichrangiger Fullscreen-Pässe zwischen Szene und Blit, Ping-Pong über zwei interne Targets. Der Vertrag ist für alle gleich: Farbtextur rein (group 0/binding 0), Farbe raus. Die Vertex-Stufe teilen sich alle über fullscreen.wgsl, damit eine Effekt-Datei nur aus ihrem fs_main besteht. Ein neuer Effekt ist eine .wgsl plus eine Zeile in EFFECTS. Bei 640×480 kostet ein eigener Pass je Effekt praktisch nichts — deshalb kein Über-Shader. Erster Bewohner ist die RGB555-Quantisierung samt Bayer-Dither, aus scene.wgsl herausgelöst. Das UI zeichnet jetzt in einem eigenen Pass hinter der Kette, sonst würde der Dither auch den Text quantisieren, den er bisher nicht anfasst; damit braucht SpritePass kein Tiefen-Attachment mehr. Geschaltet wird über den exec-Trichter (`post`, `post <e> on|off`). Die Namen kennt nur das Frontend: es meldet seine Kette beim Start in engine::post an, wie render::audio seine Emitter aus engine::audio zieht. Der Kern bekommt dadurch keine GPU zu sehen. Das Bild soll unverändert bleiben — gleicher Bayer-Kernel, gleiche Koordinaten, gleiche Reihenfolge relativ zum UI. Verifiziert sind Tests, clippy und ein Start ohne Validation-Fehler; ein Pixelvergleich steht aus. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
20 lines
576 B
WebGPU Shading Language
20 lines
576 B
WebGPU Shading Language
// Vertex-Stufe *aller* Post-Effekte: ein Dreieck über den ganzen Schirm.
|
|
//
|
|
// Bewusst ein eigenes Modul: die Pipeline nimmt die Vertex-Stufe von hier und
|
|
// die Fragment-Stufe aus der Effekt-Datei. So besteht eine Effekt-Datei nur
|
|
// aus ihrem `fs_main` und kennt keinen anderen Shader.
|
|
|
|
struct VsOut {
|
|
@builtin(position) pos: vec4f,
|
|
};
|
|
|
|
@vertex
|
|
fn vs_main(@builtin(vertex_index) i: u32) -> VsOut {
|
|
var xy = array<vec2f, 3>(
|
|
vec2f(-1.0, -1.0), vec2f(3.0, -1.0), vec2f(-1.0, 3.0),
|
|
);
|
|
var o: VsOut;
|
|
o.pos = vec4f(xy[i], 0.0, 1.0);
|
|
return o;
|
|
}
|