From 074fb102631021a21a9cee3eb69d6b918c797004 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl <dpjudas@users.noreply.github.com> Date: Wed, 1 May 2019 00:55:31 +0200 Subject: [PATCH] - use the exact sRGB->linear transfer function in HDR mode as the 2.2 gamma approximation is visibly inaccurate in this case --- src/rendering/gl/renderer/gl_postprocess.cpp | 3 ++- src/rendering/gl/renderer/gl_stereo3d.cpp | 1 + .../hwrenderer/postprocessing/hw_postprocess.h | 3 ++- src/rendering/vulkan/renderer/vk_postprocess.cpp | 6 +++++- wadsrc/static/shaders/glsl/present.fp | 15 ++++++++++++++- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/rendering/gl/renderer/gl_postprocess.cpp b/src/rendering/gl/renderer/gl_postprocess.cpp index c233b80c7a..85e802a4fb 100644 --- a/src/rendering/gl/renderer/gl_postprocess.cpp +++ b/src/rendering/gl/renderer/gl_postprocess.cpp @@ -225,11 +225,12 @@ void FGLRenderer::DrawPresentTexture(const IntRect &box, bool applyGamma) { // Full screen exclusive mode treats a rgba16f frame buffer as linear. // It probably will eventually in desktop mode too, but the DWM doesn't seem to support that. - mPresentShader->Uniforms->InvGamma *= 2.2f; + mPresentShader->Uniforms->HdrMode = 1; mPresentShader->Uniforms->ColorScale = (gl_dither_bpc == -1) ? 1023.0f : (float)((1 << gl_dither_bpc) - 1); } else { + mPresentShader->Uniforms->HdrMode = 0; mPresentShader->Uniforms->ColorScale = (gl_dither_bpc == -1) ? 255.0f : (float)((1 << gl_dither_bpc) - 1); } mPresentShader->Uniforms->Scale = { screen->mScreenViewport.width / (float)mBuffers->GetWidth(), screen->mScreenViewport.height / (float)mBuffers->GetHeight() }; diff --git a/src/rendering/gl/renderer/gl_stereo3d.cpp b/src/rendering/gl/renderer/gl_stereo3d.cpp index d2bceaeaa9..9483310ba5 100644 --- a/src/rendering/gl/renderer/gl_stereo3d.cpp +++ b/src/rendering/gl/renderer/gl_stereo3d.cpp @@ -167,6 +167,7 @@ void FGLRenderer::prepareInterleavedPresent(FPresentShaderBase& shader) shader.Uniforms->Saturation = clamp<float>(vid_saturation, -15.0f, 15.0f); shader.Uniforms->GrayFormula = static_cast<int>(gl_satformula); } + shader.Uniforms->HdrMode = 0; shader.Uniforms->ColorScale = (gl_dither_bpc == -1) ? 255.0f : (float)((1 << gl_dither_bpc) - 1); shader.Uniforms->Scale = { screen->mScreenViewport.width / (float)mBuffers->GetWidth(), diff --git a/src/rendering/hwrenderer/postprocessing/hw_postprocess.h b/src/rendering/hwrenderer/postprocessing/hw_postprocess.h index 902810c7c6..61dbf47027 100644 --- a/src/rendering/hwrenderer/postprocessing/hw_postprocess.h +++ b/src/rendering/hwrenderer/postprocessing/hw_postprocess.h @@ -726,7 +726,7 @@ struct PresentUniforms FVector2 Scale; FVector2 Offset; float ColorScale; - float Padding; + int HdrMode; static std::vector<UniformFieldDesc> Desc() { @@ -741,6 +741,7 @@ struct PresentUniforms { "UVScale", UniformType::Vec2, offsetof(PresentUniforms, Scale) }, { "UVOffset", UniformType::Vec2, offsetof(PresentUniforms, Offset) }, { "ColorScale", UniformType::Float, offsetof(PresentUniforms, ColorScale) }, + { "HdrMode", UniformType::Int, offsetof(PresentUniforms, HdrMode) } }; } }; diff --git a/src/rendering/vulkan/renderer/vk_postprocess.cpp b/src/rendering/vulkan/renderer/vk_postprocess.cpp index 3bb441f190..db82eb3bf5 100644 --- a/src/rendering/vulkan/renderer/vk_postprocess.cpp +++ b/src/rendering/vulkan/renderer/vk_postprocess.cpp @@ -200,7 +200,11 @@ void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool if (applyGamma && fb->swapChain->swapChainFormat.colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT) { - uniforms.InvGamma *= 2.2f; + uniforms.HdrMode = 1; + } + else + { + uniforms.HdrMode = 0; } renderstate.Clear(); diff --git a/wadsrc/static/shaders/glsl/present.fp b/wadsrc/static/shaders/glsl/present.fp index 6a484f7a32..7069d0fae5 100644 --- a/wadsrc/static/shaders/glsl/present.fp +++ b/wadsrc/static/shaders/glsl/present.fp @@ -29,7 +29,20 @@ vec4 Dither(vec4 c) return vec4(floor(c.rgb * ColorScale + threshold) / ColorScale, c.a); } +vec4 sRGBtoLinear(vec4 c) +{ + return vec4(mix(pow((c.rgb + 0.055) / 1.055, vec3(2.4)), c.rgb / 12.92, step(c.rgb, vec3(0.04045))), c.a); +} + +vec4 ApplyHdrMode(vec4 c) +{ + if (HdrMode == 0) + return c; + else + return sRGBtoLinear(c); +} + void main() { - FragColor = Dither(ApplyGamma(texture(InputTexture, UVOffset + TexCoord * UVScale))); + FragColor = Dither(ApplyHdrMode(ApplyGamma(texture(InputTexture, UVOffset + TexCoord * UVScale)))); }