power_play/res/sh/blit.hlsl

95 lines
2.4 KiB
HLSL

#include "sh/common.hlsl"
/* ========================== *
* Root signature
* ========================== */
#define ROOTSIG \
"RootConstants(num32BitConstants = 20, b0), " \
"DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
\
"StaticSampler(s0, " \
"filter = FILTER_MIN_MAG_MIP_POINT, " \
"addressU = TEXTURE_ADDRESS_CLAMP, " \
"addressV = TEXTURE_ADDRESS_CLAMP, " \
"addressW = TEXTURE_ADDRESS_CLAMP, " \
"maxAnisotropy = 1)"
ConstantBuffer<struct sh_blit_constants> g_constants : register(b0);
Texture2D g_textures[] : register(t0);
SamplerState g_sampler : register(s0);
/* ========================== *
* Vertex shader
* ========================== */
struct vs_input {
DECLS(uint, SV_VertexID);
};
struct vs_output {
DECLS(float4, SV_Position);
DECLS(float2, uv);
};
SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input)
{
static const float2 unit_quad_verts[4] = {
float2(-0.5f, -0.5f),
float2(0.5f, -0.5f),
float2(0.5f, 0.5f),
float2(-0.5f, 0.5f)
};
float2 vert = unit_quad_verts[input.SV_VertexID];
struct vs_output output;
output.SV_Position = mul(g_constants.projection, float4(vert, 0, 1));
output.uv = vert + 0.5;
return output;
}
/* ========================== *
* Tone map
* ========================== */
/* ACES approximation by Krzysztof Narkowicz
* https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ */
INLINE float3 tone_map(float3 v)
{
return saturate((v * (2.51f * v + 0.03f)) / (v * (2.43f * v + 0.59f) + 0.14f));
}
/* ========================== *
* Pixel shader
* ========================== */
struct ps_input {
struct vs_output vs;
};
struct ps_output {
DECLS(float4, SV_Target);
};
SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
{
struct ps_output output;
float4 color = g_textures[g_constants.tex_urid].Sample(g_sampler, input.vs.uv);
/* Apply tone map */
if (g_constants.flags & SH_BLIT_FLAG_TONE_MAP) {
/* TODO: Dynamic exposure based on average scene luminance */
color.rgb = tone_map(color.rgb) * g_constants.exposure;
}
/* Apply gamma correction */
if (g_constants.flags & SH_BLIT_FLAG_GAMMA_CORRECT) {
color = pow(abs(color), 1/g_constants.gamma);
}
output.SV_Target = color;
return output;
}