fullscreen.slang

cross platform rendering playground

src/passes/fullscreen/fullscreen.slang

2.26 KB
#include "shared.h"
#include "renderer_types.h"

vec3 to_srgb(vec3 x) {
    return clamp(select(x <= 0.0031308, x * 12.92, 1.055 * pow(x, 1.0 / 2.2) - 0.055), 0.0, 1.0);
}

inline vec3 tonemapFilmic(vec3 color) {
    vec3 temp = max(vec3(0.0F), color - vec3(0.004F));
    vec3 result = (temp * (vec3(6.2F) * temp + vec3(0.5F))) / (temp * (vec3(6.2F) * temp + vec3(1.7F)) + vec3(0.06F));
    return result;
}

/*-------------------------------------------------------------------------------------------------
# Function `tonemapUncharted`
> Tone mapping operator from Uncharted 2 by John Hable. sRGB correction is built in.

See: http://filmicworlds.com/blog/filmic-tonemapping-operators/
-------------------------------------------------------------------------------------------------*/

inline vec3 tonemapUncharted2Impl(vec3 color) {
    const f32 a = 0.15F;
    const f32 b = 0.50F;
    const f32 c = 0.10F;
    const f32 d = 0.20F;
    const f32 e = 0.02F;
    const f32 f = 0.30F;
    return ((color * (a * color + c * b) + d * e) / (color * (a * color + b) + d * f)) - e / f;
}

inline vec3 tonemapUncharted2(vec3 color) {
    const f32 W = 11.2F;
    const f32 exposure_bias = 2.0F;
    color = tonemapUncharted2Impl(color * exposure_bias);
    vec3 white_scale = vec3(1.0F) / tonemapUncharted2Impl(vec3(W));
    return pow(color * white_scale, vec3(1.0F / 2.2F));
}

[vk::push_constant]
FullscreenPushConstants pc;

[shader("vertex")]
VtxOut vsMain(u32 vertexID: SV_VertexID) {
    VtxOut o;
    o.uv = vec2((vertexID << 1) & 2, vertexID & 2);
    o.clip_pos = vec4(o.uv * 2.0f - 1.0f, 0.0f, 1.0f);
    return o;
}

[shader("fragment")]
vec4 fsMain(VtxOut input) : SV_Target {
    // yikes on this
    // wrap up ssr or dump but get rid of this line
    Texture2D.Handle ssr_null = reinterpret<Texture2D.Handle>(uint2(0xFFFFFFFFu, 0xFFFFFFFFu));
    vec4 main = pc.lighting.Sample(pc.samp, input.uv);
    vec3 ssr = vec3(0.0f);
    if (pc.ssr != ssr_null) {
        ssr = pc.ssr.Sample(pc.samp, input.uv).rgb;
    }

    vec3 comp = main.rgb + ssr;

    f32 EV = 2.0f;
    f32 exposure = exp2(EV);
    vec4 hdr = vec4(comp, main.a) * exposure; // + ssr;

    // vec3 out = tonemapFilmic(hdr.rgb);
    vec3 out = tonemapUncharted2(comp);
    // vec3 out = to_srgb(hdr.rgb);

    return vec4(out, main.a);
}