From 5056777b861230abb45c66b50bd2198846915f29 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Wed, 23 May 2018 16:52:40 +0200 Subject: vo_gpu: desaturate after peak detection This sacrifices some dynamic range for well-behaved sources, but prevents catastrophic desaturation on badly mastered / too bright sources. I think that's the better trade-off. This makes the desaturation algorithm much "safer" to deploy by default, as well. One could even argue going up to strength 1.0, which works better for some sources but worse for others. But I think the current strength is the best trade-off even after this change. --- video/out/gpu/video_shaders.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/video/out/gpu/video_shaders.c b/video/out/gpu/video_shaders.c index 19fb0ccde8..2b18d172db 100644 --- a/video/out/gpu/video_shaders.c +++ b/video/out/gpu/video_shaders.c @@ -655,18 +655,6 @@ static void pass_tone_map(struct gl_shader_cache *sc, bool detect_peak, GLSLF("float sig_peak = %f;\n", src_peak); GLSLF("float sig_avg = %f;\n", sdr_avg); - // Desaturate the color using a coefficient dependent on the signal - // Do this before peak detection in order to try and reclaim as much - // dynamic range as possible. - if (desat > 0) { - float base = 0.18 * dst_peak; - GLSL(float luma = dot(dst_luma, color.rgb);) - GLSLF("float coeff = max(sig - %f, 1e-6) / max(sig, 1e-6);\n", base); - GLSLF("coeff = pow(coeff, %f);\n", 10.0 / desat); - GLSL(color.rgb = mix(color.rgb, vec3(luma), coeff);) - GLSL(sig = mix(sig, luma, coeff);) // also make sure to update `sig` - } - if (detect_peak) hdr_update_peak(sc); @@ -683,6 +671,18 @@ static void pass_tone_map(struct gl_shader_cache *sc, bool detect_peak, GLSL(sig *= slope;) GLSL(sig_peak *= slope;) + // Desaturate the color using a coefficient dependent on the signal. + // Do this after peak detection in order to prevent over-desaturating + // overly bright souces + if (desat > 0) { + float base = 0.18 * dst_peak; + GLSL(float luma = dot(dst_luma, color.rgb);) + GLSLF("float coeff = max(sig - %f, 1e-6) / max(sig, 1e-6);\n", base); + GLSLF("coeff = pow(coeff, %f);\n", 10.0 / desat); + GLSL(color.rgb = mix(color.rgb, vec3(luma), coeff);) + GLSL(sig = mix(sig, luma * slope, coeff);) // also make sure to update `sig` + } + switch (algo) { case TONE_MAPPING_CLIP: GLSLF("sig = %f * sig;\n", isnan(param) ? 1.0 : param); -- cgit v1.2.3