viewport.wgsl

webgpu-based path tracer

src/shaders/viewport.wgsl

1.82 KB
#include utils.wgsl

@group(0) @binding(0) var output_buffer: texture_2d<f32>;

struct Interpolator {
    @builtin(position) position: vec4<f32>,
    @location(0) tex_coord: vec2<f32>,
}


fn uncharted2_tonemap_base(x : vec3f) -> vec3f
{
	let a = 0.15;
    let b = 0.50;
    let c = 0.10;
    let d = 0.20;
    let e = 0.02;
    let f = 0.30;
	return ((x*(a*x+c*b)+d*e)/(x*(a*x+b)+d*f))-e/f;
}

fn uncharted2_tonemap(color: vec3f) -> vec3f {
    let exposure = 2.0; // adjustable
    let white_point = uncharted2_tonemap_base(vec3f(11.2));
    let mapped = uncharted2_tonemap_base(color * exposure);
    return mapped / white_point;
}

fn gamma_correct(color: vec3<f32>) -> vec3<f32> {
    return pow(color, vec3<f32>(1.0 / 2.2));
}

// fn reinhard_tonemap(color: vec3<f32>) -> vec3<f32> {
//     return color / (color + vec3f(1.0));
// }


@vertex
fn vert_main(@builtin(vertex_index) vertex_index: u32) -> Interpolator {
    var positions = array<vec2<f32>, 6>(
        vec2<f32>(1.0, 1.0),
        vec2<f32>(1.0, -1.0),
        vec2<f32>(-1.0, -1.0),
        vec2<f32>(1.0, 1.0),
        vec2<f32>(-1.0, -1.0),
        vec2<f32>(-1.0, 1.0)
    );
    var tex_coords = array<vec2<f32>, 6>(
        vec2<f32>(1.0, 1.0),
        vec2<f32>(1.0, 0.0),
        vec2<f32>(0.0, 0.0),
        vec2<f32>(1.0, 1.0),
        vec2<f32>(0.0, 0.0),
        vec2<f32>(0.0, 1.0)
    );
    var output: Interpolator;
    output.position = vec4<f32>(positions[vertex_index], 0.0, 1.0);
    output.tex_coord = tex_coords[vertex_index];
    return output;
}

@fragment
fn frag_main(@location(0) tex_coord: vec2<f32>) -> @location(0) vec4<f32> {
    let dims = textureDimensions(output_buffer);
    let uv = vec2<u32>(tex_coord * vec2<f32>(dims));
    let linear_color = textureLoad(output_buffer, uv, 0).rgb;
    return vec4f(gamma_correct(uncharted2_tonemap(linear_color)), 1.0);
}