Skip to main content

RESOLVE_WGSL

Constant RESOLVE_WGSL 

Source
pub const RESOLVE_WGSL: &str = "\nfn ssr_encode_normal(n: vec3f) -> vec2f {\n    let p = n.xy / (abs(n.x) + abs(n.y) + abs(n.z));\n    if (n.z >= 0.0) { return p; }\n    return (vec2f(1.0) - abs(p.yx)) * select(vec2f(-1.0), vec2f(1.0), p >= vec2f(0.0));\n}\nfn ssr_decode_normal(e: vec2f) -> vec3f {\n    var n = vec3f(e, 1.0 - abs(e.x) - abs(e.y));\n    let t = max(-n.z, 0.0);\n    n.x += select(t, -t, n.x >= 0.0);\n    n.y += select(t, -t, n.y >= 0.0);\n    return normalize(n);\n}\nfn ssr_similarity(depth: f32, normal: vec3f, other_depth: f32, other_normal: vec3f, tolerance: f32) -> f32 {\n    if (depth <= 0.0 || other_depth <= 0.0) { return 0.0; }\n    let near = clamp(1.0 - abs(depth - other_depth) / max(tolerance, 0.000001), 0.0, 1.0);\n    let facing = smoothstep(0.6, 0.85, dot(normal, other_normal));\n    return near * facing;\n}\nconst SSR_DEPTH_TOLERANCE: f32 = 0.03;\n\nstruct ReflectParams {\n    size: vec2u,\n    half_size: vec2u,\n    projection: mat4x4f,\n    inverse_projection: mat4x4f,\n    history_valid: u32,\n    frame_index: u32,\n    refine: u32,\n    thickness: f32,\n    history_half: vec2u,\n}\n@group(0) @binding(0) var<uniform> params: ReflectParams;\nfn inside(uv: vec2f) -> bool {\n    return all(uv >= vec2f(0.0)) && all(uv < vec2f(1.0));\n}\nfn trace_pixel(cell: vec2u) -> vec2u {\n    let phase = params.frame_index % 4u;\n    let offset = vec2u(select(0u, 1u, phase == 1u || phase == 2u), select(0u, 1u, phase == 1u || phase == 3u));\n    return min(cell * 2u + offset, params.size - 1u);\n}\n\n@group(0) @binding(1) var raw_tex: texture_2d<f32>;\n@group(0) @binding(2) var guide_tex: texture_2d<f32>;\n@group(0) @binding(3) var history_tex: texture_2d<f32>;\n@group(0) @binding(4) var history_guide: texture_2d<f32>;\n@group(0) @binding(5) var motion_tex: texture_2d<f32>;\n@group(0) @binding(6) var output_tex: texture_storage_2d<rgba16float, write>;\n@group(0) @binding(7) var guide_out: texture_storage_2d<rgba16float, write>;\n@compute @workgroup_size(8, 8)\nfn resolve_pass(@builtin(global_invocation_id) id: vec3u) {\n    if (any(id.xy >= params.half_size)) { return; }\n    let cell = vec2i(id.xy);\n    let last = vec2i(params.half_size) - vec2i(1);\n    let current = textureLoad(raw_tex, cell, 0);\n    let guide = textureLoad(guide_tex, cell, 0);\n    if (guide.x <= 0.0) {\n        textureStore(output_tex, cell, vec4f(0.0));\n        textureStore(guide_out, cell, vec4f(0.0));\n        return;\n    }\n    let normal = ssr_decode_normal(guide.yz);\n    let right = textureLoad(guide_tex, clamp(cell + vec2i(1, 0), vec2i(0), last), 0);\n    let down = textureLoad(guide_tex, clamp(cell + vec2i(0, 1), vec2i(0), last), 0);\n    let diagonal = textureLoad(guide_tex, clamp(cell + vec2i(1, 1), vec2i(0), last), 0);\n    let slope = min(max(abs(right.x - guide.x), abs(down.x - guide.x)), guide.x * SSR_DEPTH_TOLERANCE);\n    let tolerance = guide.x * SSR_DEPTH_TOLERANCE + slope;\n    let consistent = ssr_similarity(guide.x, normal, right.x, ssr_decode_normal(right.yz), tolerance) > 0.8\n        && ssr_similarity(guide.x, normal, down.x, ssr_decode_normal(down.yz), tolerance) > 0.8\n        && ssr_similarity(guide.x, normal, diagonal.x, ssr_decode_normal(diagonal.yz), tolerance + slope) > 0.8;\n    textureStore(guide_out, cell, vec4f(guide.xyz, select(-1.0 - guide.w, guide.w, consistent)));\n    var low = current;\n    var high = current;\n    for (var i = 0; i < 4; i++) {\n        let offset = select(vec2i(0, select(-1, 1, i == 3)), vec2i(select(-1, 1, i == 1), 0), i < 2);\n        let near = textureLoad(raw_tex, clamp(cell + offset, vec2i(0), last), 0);\n        low = min(low, near);\n        high = max(high, near);\n    }\n    var result = current;\n    let pixel = trace_pixel(id.xy);\n    let prev = (vec2f(pixel) + vec2f(0.5)) / vec2f(params.size) + textureLoad(motion_tex, vec2i(pixel), 0).rg;\n    if (params.history_valid != 0u && inside(prev)) {\n        let history_last = vec2i(params.history_half) - vec2i(1);\n        let f = prev * vec2f(params.history_half) - vec2f(0.5);\n        let base = vec2i(floor(f));\n        let t = f - floor(f);\n        var sum = vec4f(0.0);\n        var total = 0.0;\n        var coverage = 0.0;\n        for (var i = 0; i < 4; i++) {\n            let offset = vec2i(i & 1, i >> 1u);\n            let at = clamp(base + offset, vec2i(0), history_last);\n            let bilinear = select(1.0 - t.x, t.x, offset.x == 1) * select(1.0 - t.y, t.y, offset.y == 1);\n            let g = textureLoad(history_guide, at, 0);\n            let similar = ssr_similarity(guide.x, normal, g.x, ssr_decode_normal(g.yz), tolerance);\n            let weight = (bilinear + 0.01) * similar;\n            sum += textureLoad(history_tex, at, 0) * weight;\n            total += weight;\n            coverage += bilinear * similar;\n        }\n        if (total > 0.001 && coverage > 0.001) {\n            let old = clamp(sum / total, low, high);\n            let weight = mix(0.6, 0.9, clamp(guide.w, 0.0, 1.0)) * clamp(coverage * 2.0, 0.0, 1.0);\n            result = mix(current, old, weight);\n        }\n    }\n    textureStore(output_tex, cell, result);\n}\n";