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