]> git.tdb.fi Git - libs/gl.git/commitdiff
Improve the color curve postprocessor
authorMikko Rasa <tdb@tdb.fi>
Mon, 28 Nov 2016 21:31:19 +0000 (23:31 +0200)
committerMikko Rasa <tdb@tdb.fi>
Mon, 28 Nov 2016 21:31:19 +0000 (23:31 +0200)
shaderlib/colorcurve.glsl
source/colorcurve.cpp
source/colorcurve.h

index fa3ba5107600f36f9a9e7b559b31e2b8fb5bf408..63f63138145a2dd73a1d4f82d7542007d3ba90ac 100644 (file)
@@ -3,27 +3,22 @@ import postprocess;
 uniform sampler1D curve;
 uniform ToneMapping
 {
 uniform sampler1D curve;
 uniform ToneMapping
 {
-       float peak;
-       float brightness;
+       float exposure;
+       vec3 brightness_response;
 };
 
 ////// fragment
 void main()
 {
 };
 
 ////// fragment
 void main()
 {
-       vec4 sample = texture(source, texcoord);
-       float maxc = max(sample.r, max(sample.g, sample.b));
-       if(maxc>1.0-peak)
+       vec4 incoming = texture(source, texcoord);
+       float maxc = max(incoming.r, max(incoming.g, incoming.b));
+       if(maxc>0.0)
        {
        {
-               vec3 saturated = sample.rgb/maxc;
-               if(maxc>1.0+peak)
-               {
-                       sample.rgb = mix(vec3(1.0), saturated, 1.0/pow(brightness, maxc-1.0-peak));
-               }
-               else
-               {
-                       float x = (1.0+peak-maxc)/(2.0*peak);
-                       sample.rgb = saturated.rgb*(1.0-peak+(1.0-x*x)*peak);
-               }
+               vec3 saturated = incoming.rgb/maxc;
+               maxc = pow(maxc*exposure+brightness_response.y, brightness_response.x)-brightness_response.z;
+               float c = min(maxc, 1.0);
+               float minc = min(saturated.r, min(saturated.g, saturated.b));
+               incoming.rgb = mix(saturated, vec3(1.0), min((maxc-c)/(1.0-minc), 1.0))*c;
        }
        }
-       frag_color = vec4(texture(curve, sample.r).r, texture(curve, sample.g).r, texture(curve, sample.b).r, sample.a);
+       frag_color = vec4(texture(curve, incoming.r).r, texture(curve, incoming.g).r, texture(curve, incoming.b).r, incoming.a);
 }
 }
index 81b5a43e7a6ef4d6724a39e2ea182e7ecd63586a..f1c090308458b4edbf9360d5018a80d817389471 100644 (file)
@@ -23,23 +23,31 @@ ColorCurve::ColorCurve():
        curve.set_wrap(CLAMP_TO_EDGE);
        texturing.attach(1, curve);
 
        curve.set_wrap(CLAMP_TO_EDGE);
        texturing.attach(1, curve);
 
-       set_peak(0.2);
-       set_brightness(1.5);
+       set_exposure_adjust(0.0f);
+       set_brightness_response(0.4f);
        set_linear();
 }
 
        set_linear();
 }
 
-void ColorCurve::set_peak(float p)
+void ColorCurve::set_exposure_adjust(float e)
+{
+       shdata.uniform("exposure", pow(2.0f, e));
+}
+
+void ColorCurve::set_brightness_response(float b)
+{
+       if(b<=0 || b>1)
+               throw invalid_argument("ColorCurve::set_brightness_response");
+       float t = (b<1 ? pow(b, 1/(1-b)) : 0.0f);
+       shdata.uniform("brightness_response", b, t, pow(t, b));
+}
+
+void ColorCurve::set_peak(float)
 {
 {
-       if(p<0 || p>1)
-               throw invalid_argument("ColorCurve::set_peak");
-       shdata.uniform("peak", p);
 }
 
 void ColorCurve::set_brightness(float b)
 {
 }
 
 void ColorCurve::set_brightness(float b)
 {
-       if(b<1)
-               throw invalid_argument("ColorCurve::set_brightness");
-       shdata.uniform("brightness", b);
+       set_brightness_response(1/b);
 }
 
 void ColorCurve::set_gamma(float g)
 }
 
 void ColorCurve::set_gamma(float g)
index 2b854bec8b6f8ac5392f010e64a06b5269b83415..608af44888ce9edcc3030d135cac98abb3728772 100644 (file)
@@ -12,8 +12,8 @@ namespace GL {
 
 /**
 Processes oversaturated colors to preserve hues.  When one color component
 
 /**
 Processes oversaturated colors to preserve hues.  When one color component
-exceeds 1.0, the others are scaled towards white.  A transition curve is also
-applied near 1.0 to prevent the abrupt change in the gradient.
+exceeds 1.0, the overflow is distributed to the other components, scaling the
+color towards white.
 
 Gamma or sRGB correction can also be applied to the output.  It can be used to
 improve color reproduction by performing lighting calculations in linear color
 
 Gamma or sRGB correction can also be applied to the output.  It can be used to
 improve color reproduction by performing lighting calculations in linear color
@@ -31,12 +31,15 @@ private:
 public:
        ColorCurve();
 
 public:
        ColorCurve();
 
-       /// Sets the size of the peak zone.  Must be between 0 and 1, inclusive.
-       void set_peak(float);
+       /** Set exposure adjustment in EV units.  Positive values brighten the
+       image, negative values darken it.  Zero is neutral. */
+       void set_exposure_adjust(float);
+
+       /** Sets the exponent of the */
+       void set_brightness_response(float);
 
 
-       /** Sets brightness for oversaturated colors.  Must be >= 1.  Suggested
-       values are between 1.5 and 2.0; a value of 1.0 will clamp colors to the
-       saturated value. */
+       // Deprecated functions
+       void set_peak(float);
        void set_brightness(float);
 
        /** Sets the gamma value used for mapping output colors.  Allowed range is
        void set_brightness(float);
 
        /** Sets the gamma value used for mapping output colors.  Allowed range is