mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-12 13:08:50 +01:00
[hud] Support HDR color spaces
Blending is broken if we need to do encoding in the shader, but we cannot do much about that without changing the rendering process, so this will have to do for now.
This commit is contained in:
parent
0e503ce795
commit
599357721a
@ -79,7 +79,10 @@ namespace dxvk::hud {
|
||||
const Rc<DxvkContext>& ctx,
|
||||
VkSurfaceFormatKHR surfaceFormat,
|
||||
VkExtent2D surfaceSize) {
|
||||
bool isSrgb = lookupFormatInfo(surfaceFormat.format)->flags.test(DxvkFormatFlag::ColorSpaceSrgb);
|
||||
VkColorSpaceKHR colorSpace = surfaceFormat.colorSpace;
|
||||
|
||||
if (lookupFormatInfo(surfaceFormat.format)->flags.test(DxvkFormatFlag::ColorSpaceSrgb))
|
||||
colorSpace = VK_COLOR_SPACE_PASS_THROUGH_EXT;
|
||||
|
||||
VkViewport viewport;
|
||||
viewport.x = 0.0f;
|
||||
@ -97,7 +100,7 @@ namespace dxvk::hud {
|
||||
ctx->setRasterizerState(m_rsState);
|
||||
ctx->setBlendMode(0, m_blendMode);
|
||||
|
||||
ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, isSrgb);
|
||||
ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, colorSpace);
|
||||
m_renderer.beginFrame(ctx, surfaceSize, m_scale);
|
||||
}
|
||||
|
||||
|
68
src/dxvk/hud/shaders/hud_frag_common.glsl
Normal file
68
src/dxvk/hud/shaders/hud_frag_common.glsl
Normal file
@ -0,0 +1,68 @@
|
||||
#define VK_COLOR_SPACE_SRGB_NONLINEAR_KHR (0)
|
||||
#define VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT (1000104002)
|
||||
#define VK_COLOR_SPACE_HDR10_ST2084_EXT (1000104008)
|
||||
#define VK_COLOR_SPACE_PASS_THROUGH_EXT (1000104013)
|
||||
|
||||
#define HUD_NITS (203.0f)
|
||||
|
||||
const mat3 rec709_to_xyz = mat3(
|
||||
0.4123908, 0.2126390, 0.0193308,
|
||||
0.3575843, 0.7151687, 0.1191948,
|
||||
0.1804808, 0.0721923, 0.9505322);
|
||||
|
||||
const mat3 xyz_to_rec2020 = mat3(
|
||||
1.7166512, -0.6666844, 0.0176399,
|
||||
-0.3556708, 1.6164812, -0.0427706,
|
||||
-0.2533663, 0.0157685, 0.9421031);
|
||||
|
||||
const mat3 rec709_to_rec2020 = xyz_to_rec2020 * rec709_to_xyz;
|
||||
|
||||
// Spec constants must always default to
|
||||
// zero for DXVK to handle them properly
|
||||
layout(constant_id = 0) const uint hud_color_space = 0;
|
||||
|
||||
vec3 encodeSrgb(vec3 linear) {
|
||||
bvec3 isLo = lessThanEqual(linear, vec3(0.0031308f));
|
||||
|
||||
vec3 loPart = linear * 12.92f;
|
||||
vec3 hiPart = pow(linear, vec3(5.0f / 12.0f)) * 1.055f - 0.055f;
|
||||
return mix(hiPart, loPart, isLo);
|
||||
}
|
||||
|
||||
vec3 encodePq(vec3 nits) {
|
||||
const float c1 = 0.8359375f;
|
||||
const float c2 = 18.8515625f;
|
||||
const float c3 = 18.6875f;
|
||||
const float m1 = 0.1593017578125f;
|
||||
const float m2 = 78.84375f;
|
||||
|
||||
vec3 y = clamp(nits / 10000.0f, vec3(0.0f), vec3(1.0f));
|
||||
vec3 y_m1 = pow(y, vec3(m1));
|
||||
|
||||
vec3 num = c1 + c2 * y_m1;
|
||||
vec3 den = 1.0f + c3 * y_m1;
|
||||
|
||||
return pow(num / den, vec3(m2));
|
||||
}
|
||||
|
||||
vec3 encodeScRgb(vec3 nits) {
|
||||
return nits / 80.0f;
|
||||
}
|
||||
|
||||
vec3 encodeOutput(vec3 linear) {
|
||||
switch (hud_color_space) {
|
||||
default:
|
||||
return linear;
|
||||
|
||||
case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
|
||||
return encodeSrgb(linear);
|
||||
|
||||
case VK_COLOR_SPACE_HDR10_ST2084_EXT: {
|
||||
vec3 rec2020 = rec709_to_rec2020 * linear;
|
||||
return encodePq(rec2020 * HUD_NITS);
|
||||
}
|
||||
|
||||
case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
|
||||
return encodeScRgb(linear * HUD_NITS);
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
#version 450
|
||||
|
||||
layout(constant_id = 0) const bool srgbSwapchain = false;
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
|
||||
#include "hud_frag_common.glsl"
|
||||
|
||||
layout(location = 0) in vec2 v_coord;
|
||||
layout(location = 0) out vec4 o_color;
|
||||
@ -24,14 +26,6 @@ uniform push_data_t {
|
||||
vec2 scale;
|
||||
};
|
||||
|
||||
vec3 linearToSrgb(vec3 color) {
|
||||
bvec3 isLo = lessThanEqual(color, vec3(0.0031308f));
|
||||
|
||||
vec3 loPart = color * 12.92f;
|
||||
vec3 hiPart = pow(color, vec3(5.0f / 12.0f)) * 1.055f - 0.055f;
|
||||
return mix(hiPart, loPart, isLo);
|
||||
}
|
||||
|
||||
void main() {
|
||||
float cx = v_coord.x * float(count);
|
||||
float fx = fract(cx);
|
||||
@ -53,9 +47,7 @@ void main() {
|
||||
o_color = mix(
|
||||
unpackUnorm4x8(p0.color),
|
||||
unpackUnorm4x8(p1.color), fx);
|
||||
|
||||
if (!srgbSwapchain)
|
||||
o_color.rgb = linearToSrgb(o_color.rgb);
|
||||
|
||||
o_color *= alpha;
|
||||
}
|
||||
|
||||
o_color.rgb = encodeOutput(o_color.rgb);
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#version 450
|
||||
|
||||
layout(constant_id = 0) const bool srgbSwapchain = false;
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
|
||||
#include "hud_frag_common.glsl"
|
||||
|
||||
layout(binding = 2) uniform sampler2D s_font;
|
||||
|
||||
@ -9,14 +11,6 @@ layout(location = 1) in vec4 v_color;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
vec3 linearToSrgb(vec3 color) {
|
||||
bvec3 isLo = lessThanEqual(color, vec3(0.0031308f));
|
||||
|
||||
vec3 loPart = color * 12.92f;
|
||||
vec3 hiPart = pow(color, vec3(5.0f / 12.0f)) * 1.055f - 0.055f;
|
||||
return mix(hiPart, loPart, isLo);
|
||||
}
|
||||
|
||||
float sampleAlpha(float alpha_bias, float dist_range) {
|
||||
float value = textureLod(s_font, v_texcoord, 0).r + alpha_bias - 0.5f;
|
||||
float dist = value * dot(vec2(dist_range, dist_range), 1.0f / fwidth(v_texcoord.xy));
|
||||
@ -34,6 +28,5 @@ void main() {
|
||||
o_color.a = r_alpha_shadow * v_color.a;
|
||||
o_color.rgb *= o_color.a;
|
||||
|
||||
if (!srgbSwapchain)
|
||||
o_color.rgb = linearToSrgb(o_color.rgb);
|
||||
o_color.rgb = encodeOutput(o_color.rgb);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user