]> 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
 {
-       float peak;
-       float brightness;
+       float exposure;
+       vec3 brightness_response;
 };
 
 ////// 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);
 
-       set_peak(0.2);
-       set_brightness(1.5);
+       set_exposure_adjust(0.0f);
+       set_brightness_response(0.4f);
        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)
 {
-       if(b<1)
-               throw invalid_argument("ColorCurve::set_brightness");
-       shdata.uniform("brightness", b);
+       set_brightness_response(1/b);
 }
 
 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
-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
@@ -31,12 +31,15 @@ private:
 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