varying vec2 		texcoord;
uniform sampler2D 	tex;

uniform vec3		colorize;
uniform float		saturate;
uniform float       vibrance;
uniform vec3		contrast,
					brightness;
uniform vec3		vign;		//x=radius, y=soft, z=scale
					
uniform vec3		inGamma,
					inBlack,
					inWhite,
					outBlack,
					outWhite;
					
uniform vec3 		RGB_Lift,
					RGB_Gain,
					RGB_Gamma;

vec3				one=vec3(1.0,1.0,1.0);
vec3				hlf=vec3(0.5,0.5,0.5);

vec3 			rmul,
				rscr;
vec4 			color;
float			lum;
float			OneMinusSat,
				lumsat;
				
vec3 ComputeVibrance( vec3 colorInput )
{
	vec3 color = colorInput;
	vec3 lumCoeff = vec3(0.3,0.59,0.11); //(0.2126, 0.7152, 0.0722);  												//Values to calculate luma with

	float luma = dot(lumCoeff, color.rgb); 														//calculate luma (grey) 

	float max_color = max(max(colorInput.r,colorInput.g),colorInput.b); 						//Find the strongest color
	float min_color = min(min(colorInput.r,colorInput.g),colorInput.b); 						//Find the weakest color
	
	float color_saturation = max_color - min_color; 											//The difference between the two is the saturation
 
	color = mix(vec3(luma), color, (1.0 + (vibrance * (1.0 - (sign(vibrance) * color_saturation))))); //extrapolate between luma and original by 1 + (1-saturation)

	return color; //return the result
}

void main()
{
	color=texture2D(tex,texcoord);
	color.rgb=pow(color.rgb,vec3(2.2));
	vec3 colorInput=color.rgb;
	
	///// VIGNETTE //////////////////////////////////////////

    //determine center position
    //vec2 position = (gl_FragCoord.xy / resolution.xy) - vec2(0.5);
	float r2 = (texcoord.x-0.5) * (texcoord.x-0.5) + (texcoord.y-0.5) * (texcoord.y-0.5);      

    //use smoothstep to create a smooth vignette
    float vignette = smoothstep(vign.x, vign.x-vign.y, r2);

    //apply the vignette with 50% opacity
    color.rgb = mix(color.rgb, color.rgb * vignette, vign.z);
	
	// desaturate
	lum=dot(color.rgb,vec3(0.3,0.59,0.11));
	OneMinusSat=saturate;
	lumsat=lum*(1.0-saturate);
	color.rgb=vec3(lumsat)+color.rgb*vec3(OneMinusSat);
	
	// vibrance
	color.rgb=ComputeVibrance(color.rgb);
	
	// -- Lift --
	color.rgb = color.rgb * (vec3(1.5)- vec3(0.5) * RGB_Lift) + vec3(0.5) * RGB_Lift - vec3(0.5);
	color.rgb = clamp(color.rgb,vec3(0.0),vec3(1.0)); //isn't strictly necessary, but doesn't cost performance.
	
	// -- Gain --
	color.rgb *= RGB_Gain; 
	
	// -- Gamma --
	colorInput = pow(color.rgb, vec3(1.0) / RGB_Gamma); //Gamma
	
	// -- Return output --
	//return (colorInput);
	color.rgb=clamp(colorInput,vec3(0.0),vec3(1.0));
	
	// BRIGHTNESS & CONTRAST
	color.xyz = ((color.xyz-hlf)*contrast) + hlf + brightness;
	
	// COLORIZATION
	rmul=color.xyz*colorize;
	rscr=one-((one-colorize)*(one-color.xyz));
	color.xyz=color.xyz*rscr+(one-color.xyz)*rmul;

	//desaturate /////////////////////////////////
/*	lum=dot(color.rgb,vec3(0.3,0.59,0.11));
	OneMinusSat=saturate;
	lumsat=lum*(1.0-saturate);
	color.rgb=vec3(lumsat)+color.rgb*vec3(OneMinusSat);
	
	// vibrance
	color.rgb=ComputeVibrance(color.rgb);
*/
	// COLOR CORRECTION	/////////////////////////
	color.rgb = pow(clamp((color.rgb - inBlack.rgb) / (inWhite.rgb - inBlack.rgb),0.0,1.0), inGamma.rgb) * (outWhite.rgb - outBlack.rgb) + outBlack.rgb;
	gl_FragColor.xyz = pow(clamp(color.rgb,vec3(0.0),vec3(1.0)),vec3(1.0/2.2));
}
