summaryrefslogtreecommitdiffstats
path: root/video/out/gl_video_shaders.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/gl_video_shaders.glsl')
-rw-r--r--video/out/gl_video_shaders.glsl34
1 files changed, 30 insertions, 4 deletions
diff --git a/video/out/gl_video_shaders.glsl b/video/out/gl_video_shaders.glsl
index b0058f8ca6..a6ecc2eeeb 100644
--- a/video/out/gl_video_shaders.glsl
+++ b/video/out/gl_video_shaders.glsl
@@ -56,6 +56,13 @@ vec3 bt2020_expand(vec3 v)
}
#endif
+// Constant matrix for conversion from BT.2020 to sRGB
+const mat3 srgb_matrix = mat3(
+ 1.6604910, -0.1245505, -0.0181508,
+ -0.5876411, 1.1328999, -0.1005789,
+ -0.0728499, -0.0083494, 1.1187297
+);
+
#!section vertex_all
#if __VERSION__ < 130
@@ -66,6 +73,7 @@ vec3 bt2020_expand(vec3 v)
uniform mat3 transform;
uniform sampler3D lut_3d;
+uniform mat3 cms_matrix; // transformation from file's gamut to bt.2020
in vec2 vertex_position;
in vec4 vertex_color;
@@ -89,12 +97,17 @@ void main() {
// NOTE: This always applies the true BT2020, maybe we need to use
// approx-gamma here too?
#endif
+#ifdef USE_OSD_CMS_MATRIX
+ // Convert to the right target gamut first (to BT.709 for sRGB,
+ // and to BT.2020 for 3DLUT).
+ color.rgb = clamp(cms_matrix * color.rgb, 0, 1);
+#endif
#ifdef USE_OSD_3DLUT
color.rgb = pow(color.rgb, vec3(1/2.4)); // linear -> 2.4 3DLUT space
color = vec4(texture3D(lut_3d, color.rgb).rgb, color.a);
#endif
#ifdef USE_OSD_SRGB
- color.rgb = srgb_compand(color.rgb);
+ color.rgb = srgb_compand(clamp(srgb_matrix * color.rgb, 0, 1));
#endif
texcoord = vertex_texcoord;
@@ -136,6 +149,7 @@ uniform sampler2D lut_l_2d;
uniform sampler3D lut_3d;
uniform sampler2D dither;
uniform mat4x3 colormatrix;
+uniform mat3 cms_matrix;
uniform mat2 dither_trafo;
uniform vec3 inv_gamma;
uniform float input_gamma;
@@ -406,16 +420,28 @@ void main() {
// User-defined gamma correction factor (via the gamma sub-option)
color = pow(color, inv_gamma);
#endif
+#ifdef USE_CMS_MATRIX
+ // Convert to the right target gamut first (to BT.709 for sRGB,
+ // and to BT.2020 for 3DLUT).
+ color = cms_matrix * color;
+#endif
#ifdef USE_3DLUT
// For the 3DLUT we are arbitrarily using 2.4 as input gamma to reduce
// the amount of rounding errors, so we pull up to that space first and
// then pass it through the 3D texture.
- color = pow(color, vec3(1/2.4));
+ //
+ // The value is clamped to [0,1] first because the gamma function is not
+ // well-defined outside it. This should not be a problem because the 3dlut
+ // is not defined for values outside its boundaries either way, and no
+ // media can possibly exceed its BT.2020 source gamut either way due to
+ // that being the biggest taggable color space. This is just to avoid
+ // numerical quirks like -1e-30 turning into NaN.
+ color = pow(clamp(color, 0, 1), vec3(1/2.4));
color = texture3D(lut_3d, color).rgb;
#endif
#ifdef USE_SRGB
- // Compand from the linear scaling gamma to the sRGB output gamma
- color = srgb_compand(color.rgb);
+ // Adapt and compand from the linear BT2020 source to the sRGB output
+ color = srgb_compand(clamp(srgb_matrix * color, 0, 1));
#endif
#ifdef USE_DITHER
vec2 dither_pos = gl_FragCoord.xy / dither_size;