]> git.sesse.net Git - casparcg/blobdiff - accelerator/ogl/image/blending_glsl.h
[mixer] Merged fixed from 2.0 where contrast adjustment incorrectly worked on premult...
[casparcg] / accelerator / ogl / image / blending_glsl.h
index 7f3429d7f68dfa4435d56b4cb22519b1b9ed3bfd..326e6f7153044b4afaaf84e67882ea2a89592107 100644 (file)
@@ -30,7 +30,7 @@ static std::string get_adjustement_glsl()
                        ** http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=21057
                        */
 
-                       vec3 ContrastSaturationBrightness(vec3 color, float brt, float sat, float con)
+                       vec3 ContrastSaturationBrightness(vec4 color, float brt, float sat, float con)
                        {
                                const float AvgLumR = 0.5;
                                const float AvgLumG = 0.5;
@@ -40,11 +40,17 @@ static std::string get_adjustement_glsl()
                                                ? vec3(0.0722, 0.7152, 0.2126)
                                                : vec3(0.114, 0.587, 0.299);
 
+                               if (color.a > 0.0)
+                                       color.rgb /= color.a;
+
                                vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
-                               vec3 brtColor = color * brt;
+                               vec3 brtColor = color.rgb * brt;
                                vec3 intensity = vec3(dot(brtColor, LumCoeff));
                                vec3 satColor = mix(intensity, brtColor, sat);
                                vec3 conColor = mix(AvgLumin, satColor, con);
+
+                               conColor.rgb *= color.a;
+
                                return conColor;
                        }
 
@@ -292,13 +298,6 @@ static std::string get_chroma_glsl()
                    return 1.0 - smoothstep(1.0, chroma_softness, d);
                }
 
-               vec4 supress_spill(vec4 c, float d)
-               {
-                       float ds        = smoothstep(chroma_spill, clamp(chroma_spill + 0.2, 0, 1), d / chroma_softness);
-                   float gl = dot(grey_xfer, c);
-                   return mix(c, vec4(vec3(pow(gl, chroma_spill_darken)), gl), ds);
-               }
-
                // http://stackoverflow.com/questions/15095909/from-rgb-to-hsv-in-opengl-glsl
                vec3 rgb2hsv(vec3 c)
                {
@@ -311,11 +310,28 @@ static std::string get_chroma_glsl()
                        return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
                }
 
+               // From the same page
+               vec3 hsv2rgb(vec3 c)
+               {
+                       vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+                       vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+                       return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+               }
+
                float AngleDiff(float angle1, float angle2)
                {
                        return 0.5 - abs(abs(angle1 - angle2) - 0.5);
                }
 
+               float AngleDiffDirectional(float angle1, float angle2)
+               {
+                       float diff = angle1 - angle2;
+
+                       return diff < -0.5
+                                       ? diff + 1.0
+                                       : (diff > 0.5 ? diff - 1.0 : diff);
+               }
+
                float Distance(float actual, float target)
                {
                        return min(0.0, target - actual);
@@ -333,13 +349,30 @@ static std::string get_chroma_glsl()
                        return -hueScore * saturationBrightnessScore;
                }
 
+               vec3 supress_spill(vec3 c)
+               {
+                       float hue               = c.x;
+                       float diff              = AngleDiffDirectional(hue, chroma_target_hue);
+                       float distance  = abs(diff) / chroma_spill_suppress;
+
+                       if (distance < 1)
+                       {
+                               c.x = diff < 0
+                                               ? chroma_target_hue - chroma_spill_suppress
+                                               : chroma_target_hue + chroma_spill_suppress;
+                               c.y *= min(1.0, distance + chroma_spill_suppress_saturation);
+                       }
+
+                       return c;
+               }
+
                // Key on any color
                vec4 ChromaOnCustomColor(vec4 c)
                {
                        vec3 hsv                = rgb2hsv(c.rgb);
                        float distance  = ColorDistance(hsv);
                        float d                 = distance * -2.0 + 1.0;
-                   vec4 suppressed     = supress_spill(c.rgba, d).rgba;
+                   vec4 suppressed     = vec4(hsv2rgb(supress_spill(hsv)), 1.0);
                        float alpha             = alpha_map(d);
 
                        suppressed *= alpha;