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));
}
"#;