Skip to main content

UPSAMPLE_WGSL

Constant UPSAMPLE_WGSL 

Source
pub const UPSAMPLE_WGSL: &str = r#"
struct Frame {
    view_proj: mat4x4f, eye: vec4f, right: vec4f, up: vec4f, forward: vec4f,
    lens: vec4f, sun: vec4f, sun_color: vec4f, extent: vec4f,
    volume_lo: vec4f, volume_hi: vec4f, volume_color: vec4f, volume_control: vec4f,
}
@group(0) @binding(0) var<uniform> frame: Frame;
@group(0) @binding(1) var scene_depth: texture_2d<f32>;
@group(0) @binding(2) var low_color: texture_2d<f32>;
@group(0) @binding(3) var low_depth: texture_2d<f32>;
@vertex fn vs_main(@builtin(vertex_index) vertex: u32) -> @builtin(position) vec4f {
    let xy = array<vec2f, 3>(vec2f(-1.0,-1.0),vec2f(3.0,-1.0),vec2f(-1.0,3.0));
    return vec4f(xy[vertex], 0.0, 1.0);
}
override low_scale: f32 = 4.0;
@fragment fn fs_main(@builtin(position) position: vec4f) -> @location(0) vec4f {
    let size = min(vec2f(textureDimensions(low_color)), ceil(frame.extent.xy / low_scale));
    let point = position.xy / frame.extent.xy * size - vec2f(0.5);
    let base = vec2i(floor(point));
    let fraction = fract(point);
    let max_pixel = vec2i(size) - vec2i(1);
    let full = textureLoad(scene_depth, vec2i(position.xy), 0).x;
    var total = 0.0;
    var result = vec4f(0.0);
    var nearest = 1e30;
    var nearest_color = vec4f(0.0);
    for (var y = 0; y < 2; y++) {
        for (var x = 0; x < 2; x++) {
            let pixel = clamp(base + vec2i(x,y), vec2i(0), max_pixel);
            let depth = textureLoad(low_depth, pixel, 0).x;
            let difference = abs(full - depth);
            let color = textureLoad(low_color, pixel, 0);
            if (difference < nearest) {
                nearest = difference;
                nearest_color = color;
            }
            let spatial = select(1.0 - fraction.x, fraction.x, x == 1) * select(1.0 - fraction.y, fraction.y, y == 1);
            let weight = spatial * exp(-difference * frame.volume_control.z);
            result += color * weight;
            total += weight;
        }
    }
    return select(nearest_color, result / max(total, 0.000001), total > 0.000001);
}
"#;