filtrate 0.2.0

GPU texture filter library: built-in filters (blur, brightness, color matrix, ...) and runtime, built on filtrate-core.
Documentation
// Sharpen: standalone laplacian-detail pass (spatial filter, cannot fuse).
//
// Untiled by design: the five overlapping laplacian taps hit the GPU
// texture cache, which benchmarks as fast as workgroup shared-memory
// tiling without the barriers and threadgroup-memory occupancy cost.

@compute @workgroup_size(WORKGROUP_X, WORKGROUP_Y)
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
    let dims = vec2<u32>(uniforms.output_dimensions);
    if gid.x >= dims.x || gid.y >= dims.y {
        return;
    }
    let amount = param(0u);
    let center_coord = map_to_input(gid.xy);

    let center = load_input(center_coord);
    let top = load_input(center_coord + vec2<i32>(0, -1));
    let bottom = load_input(center_coord + vec2<i32>(0, 1));
    let left = load_input(center_coord + vec2<i32>(-1, 0));
    let right = load_input(center_coord + vec2<i32>(1, 0));

    // Laplacian kernel; alpha keeps the centre's coverage.
    let laplacian = center * 4.0 - top - bottom - left - right;
    let result = center + laplacian * amount;
    textureStore(output_texture, vec2<i32>(gid.xy), vec4<f32>(result.rgb, center.a));
}