polyscope-render 0.5.10

Rendering backend for polyscope-rs: wgpu engine, shaders, and materials
Documentation
// SSAA (Supersampling Anti-Aliasing) downsample shader
// Downsamples a high-resolution texture to screen resolution using box filtering

struct DownsampleUniforms {
    ssaa_factor: u32,
    _padding0: u32,
    _padding1: u32,
    _padding2: u32,
}

@group(0) @binding(0) var input_texture: texture_2d<f32>;
@group(0) @binding(1) var tex_sampler: sampler;
@group(0) @binding(2) var<uniform> uniforms: DownsampleUniforms;

struct VertexOutput {
    @builtin(position) position: vec4<f32>,
    @location(0) uv: vec2<f32>,
}

@vertex
fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput {
    // Fullscreen triangle
    var out: VertexOutput;
    let x = f32((vertex_index & 1u) << 2u) - 1.0;
    let y = f32((vertex_index & 2u) << 1u) - 1.0;
    out.position = vec4<f32>(x, y, 0.0, 1.0);
    out.uv = vec2<f32>((x + 1.0) * 0.5, (1.0 - y) * 0.5);
    return out;
}

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
    let factor = f32(uniforms.ssaa_factor);
    let dims = vec2<f32>(textureDimensions(input_texture));
    let texel_size = 1.0 / dims;

    // Box filter: average all samples in the SSAA grid
    // For 2x SSAA: 4 samples, for 4x SSAA: 16 samples
    var color = vec4<f32>(0.0);
    let sample_count = uniforms.ssaa_factor * uniforms.ssaa_factor;

    // Calculate the center of the first sample in the grid
    // We want to sample at the centers of the high-res pixels that map to this output pixel
    let base_uv = in.uv;

    for (var y = 0u; y < uniforms.ssaa_factor; y++) {
        for (var x = 0u; x < uniforms.ssaa_factor; x++) {
            // Offset within the SSAA grid (0.5 centers the sample in each sub-pixel)
            let offset = (vec2<f32>(f32(x), f32(y)) + 0.5) / factor - 0.5;
            let sample_uv = base_uv + offset * texel_size * factor;
            color += textureSample(input_texture, tex_sampler, sample_uv);
        }
    }

    return color / f32(sample_count);
}