70 lines
1.9 KiB
HLSL
70 lines
1.9 KiB
HLSL
Texture2D image : register(t0);
|
|
|
|
SamplerState def_sampler : register(s0);
|
|
|
|
struct FragTexWide {
|
|
float3 uuv : TEXCOORD0;
|
|
};
|
|
|
|
cbuffer ColorMatrix : register(b0) {
|
|
float4 color_vec_y;
|
|
float4 color_vec_u;
|
|
float4 color_vec_v;
|
|
float2 range_y;
|
|
float2 range_uv;
|
|
};
|
|
|
|
float3 NitsToPQ(float3 L)
|
|
{
|
|
// Constants from SMPTE 2084 PQ
|
|
static const float m1 = 2610.0 / 4096.0 / 4;
|
|
static const float m2 = 2523.0 / 4096.0 * 128;
|
|
static const float c1 = 3424.0 / 4096.0;
|
|
static const float c2 = 2413.0 / 4096.0 * 32;
|
|
static const float c3 = 2392.0 / 4096.0 * 32;
|
|
|
|
float3 Lp = pow(saturate(L / 10000.0), m1);
|
|
return pow((c1 + c2 * Lp) / (1 + c3 * Lp), m2);
|
|
}
|
|
|
|
float3 Rec709toRec2020(float3 rec709)
|
|
{
|
|
static const float3x3 ConvMat =
|
|
{
|
|
0.627402, 0.329292, 0.043306,
|
|
0.069095, 0.919544, 0.011360,
|
|
0.016394, 0.088028, 0.895578
|
|
};
|
|
return mul(ConvMat, rec709);
|
|
}
|
|
|
|
float3 scRGBTo2100PQ(float3 rgb)
|
|
{
|
|
// Convert from Rec 709 primaries (used by scRGB) to Rec 2020 primaries (used by Rec 2100)
|
|
rgb = Rec709toRec2020(rgb);
|
|
|
|
// 1.0f is defined as 80 nits in the scRGB colorspace
|
|
rgb *= 80;
|
|
|
|
// Apply the PQ transfer function on the raw color values in nits
|
|
return NitsToPQ(rgb);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
// Pixel Shader
|
|
//--------------------------------------------------------------------------------------
|
|
float2 main_ps(FragTexWide input) : SV_Target
|
|
{
|
|
float3 rgb_left = scRGBTo2100PQ(image.Sample(def_sampler, input.uuv.xz).rgb);
|
|
float3 rgb_right = scRGBTo2100PQ(image.Sample(def_sampler, input.uuv.yz).rgb);
|
|
float3 rgb = (rgb_left + rgb_right) * 0.5;
|
|
|
|
float u = dot(color_vec_u.xyz, rgb) + color_vec_u.w;
|
|
float v = dot(color_vec_v.xyz, rgb) + color_vec_v.w;
|
|
|
|
u = u * range_uv.x + range_uv.y;
|
|
v = v * range_uv.x + range_uv.y;
|
|
|
|
return float2(u, v);
|
|
}
|