// Screen decay shader - attenuates intermediate texture contents
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@vertex
fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput {
// Generate full-screen triangle:
// -> uv (0,0), (2,0), (0,2)
// -> positions (-1,1), (3,1), (-1,-3)
var out: VertexOutput;
out.uv = vec2f(f32(vertex_index & 1), f32(vertex_index >> 1)) * 2.0;
var pos: vec2f = (out.uv * 2.0 - vec2f(1., 1.));
pos.y = - pos.y;
out.position = vec4f(pos, 0.0, 1.0);
return out;
}
@group(0) @binding(0)
var<uniform> viewport: ViewportUniform;
struct ViewportUniform {
transform: mat3x3<f32>,
resolution: vec2<u32>,
beam_radius: f32,
intensity: f32,
gamma: f32,
decay_per_sample: f32,
num_samples: u32,
screen_decay: f32, // screen decay factor (0.0 = no decay, 1.0 = complete fade)
};
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
// Output black with alpha = (1 - screen_decay)
// This will multiplicatively blend to attenuate existing pixel values
let attenuation_factor = exp(-viewport.screen_decay);
return vec4<f32>(0.0, 0.0, 0.0, attenuation_factor);
}