mirror of
https://github.com/mpv-player/mpv
synced 2025-02-15 03:27:35 +00:00
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.
This commit is contained in:
parent
cb52cfae1a
commit
5056777b86
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user