Skip to main content

SHARPEN_WGSL

Constant SHARPEN_WGSL 

Source
pub const SHARPEN_WGSL: &str = r#"
struct Params {
    width: u32,
    height: u32,
    strength: f32,
    exposure: f32,
}

@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(1) var source: texture_2d<f32>;
@group(0) @binding(2) var display: texture_storage_2d<rgba16float, write>;

fn tap(p: vec2<i32>) -> vec3<f32> {
    let size = vec2<i32>(i32(params.width), i32(params.height));
    let c = max(textureLoad(source, clamp(p, vec2<i32>(0), size - vec2<i32>(1)), 0).rgb * params.exposure, vec3<f32>(0.0));
    return c / (1.0 + max(c.r, max(c.g, c.b)));
}

@compute @workgroup_size(8, 8)
fn sharpen(@builtin(global_invocation_id) gid: vec3<u32>) {
    if (gid.x >= params.width || gid.y >= params.height) {
        return;
    }
    let p = vec2<i32>(gid.xy);
    let centre = textureLoad(source, p, 0);
    let a = tap(p + vec2<i32>(-1, -1));
    let b = tap(p + vec2<i32>(0, -1));
    let c = tap(p + vec2<i32>(1, -1));
    let d = tap(p + vec2<i32>(-1, 0));
    let e = tap(p);
    let f = tap(p + vec2<i32>(1, 0));
    let g = tap(p + vec2<i32>(-1, 1));
    let h = tap(p + vec2<i32>(0, 1));
    let i = tap(p + vec2<i32>(1, 1));
    let cross_lo = min(min(min(d, e), min(f, b)), h);
    let cross_hi = max(max(max(d, e), max(f, b)), h);
    let lo = cross_lo + min(cross_lo, min(min(a, c), min(g, i)));
    let hi = cross_hi + max(cross_hi, max(max(a, c), max(g, i)));
    let amp = sqrt(clamp(min(lo, vec3<f32>(2.0) - hi) / max(hi, vec3<f32>(1.0e-5)), vec3<f32>(0.0), vec3<f32>(1.0)));
    let w = amp * (-params.strength / mix(8.0, 5.0, params.strength));
    let t = clamp((b * w + d * w + f * w + h * w + e) / (vec3<f32>(1.0) + 4.0 * w), vec3<f32>(0.0), vec3<f32>(0.999));
    let back = t / (1.0 - max(t.r, max(t.g, t.b))) / params.exposure;
    textureStore(display, p, vec4<f32>(back, centre.a));
}

@compute @workgroup_size(8, 8)
fn copy(@builtin(global_invocation_id) gid: vec3<u32>) {
    if (gid.x >= params.width || gid.y >= params.height) {
        return;
    }
    let p = vec2<i32>(gid.xy);
    textureStore(display, p, textureLoad(source, p, 0));
}
"#;