float luminance(vec3 color) {
    return dot(color, vec3(0.212, 0.7152, 0.072));
}


vec3 rgb2hsv(vec3 c)
{
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));

    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}


vec3 hsv2rgb(vec3 c)
{
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(vec3(c.x) + K.rgb) * 6.0 - vec3(K.a));
    return c.z * mix(vec3(K.x), clamp(p - vec3(K.x), 0.0, 1.0), c.y);
}

//http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl


#define saturation 1.0 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0]

#define contrast 1.0 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0]

#define vibrance 1.0 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0]

vec3 vibranceFunction(vec3 color) { //Thanks to belmu for the code
    float minChannel       = min(min(color.r,color.g),color.b);
    float maxChannel       = max(max(color.r,color.g),color.b);
    float sat      = (1.0 - clamp(maxChannel - minChannel,0.0,1.0)) * (clamp(1.0 - maxChannel,0.0,1.0) * luminance(color)) * 5.0;
    vec3 lightValue = vec3((minChannel + maxChannel) * 0.5);

    return mix(color, mix(lightValue, color, vibrance), sat); //diz = vibrance
    // return mix(color, lightValue, (1.0 - lightValue) * (1.0 - Vibrance) * 0.5 * Vibrance); // diz = negative vibrance
}

vec3 saturationFunction(vec3 scolor){
    float mixrgb = (scolor.r + scolor.g + scolor.b) / 3.5;
    float weight = (saturation) + (1.0 - pow(1.0 - 1.0 * mixrgb, 2.0)) * 0.08;

    return max(mix(vec3(mixrgb), scolor, weight),1e-5);
}

vec3 contrastFunction(vec3 scolor) {
    vec3 l = log2(scolor + 1e-4);
    l = (l + 1.0)*contrast - 1.0;
    return exp2(l)-1e-4;
}