/********************************************************
    © 2020 Continuum Graphics LLC. All Rights Reserved
 ********************************************************/

#if !defined _COLORCORRECTION_
#define _COLORCORRECTION_

struct ColorCorrection {
	vec3 lum;
	float saturation;
	float vibrance;
	
	float contrast;
	float contrastMidpoint;

	vec3 gain;
	vec3 lift;
	vec3 invGamma;
};

vec3 Saturation(const vec3 color, const ColorCorrection m) {
	float grey = dot(color, m.lum);
	return grey + m.saturation * (color - grey);
}

vec3 Vibrance(const vec3 color, const ColorCorrection m) {
	float maxColor = max3(color.r, color.g, color.b);
	float minColor = min3(color.r, color.g, color.b);

	float colorSaturation = maxColor - minColor;

	float grey = dot(color, m.lum);
	
	return mix(vec3(grey), color, 1.0 + m.vibrance * (1.0 - sign(m.vibrance) * colorSaturation));
}

vec3 LogContrast(const vec3 x, const float contrast) {
	const float contrastEpsilon = 1e-5;
	const float logMidpoint = log2(0.18);

	vec3 logX = log2(x + contrastEpsilon);
	vec3 adjX = (logX - logMidpoint) * contrast + logMidpoint;

	return max0(exp2(adjX) - contrastEpsilon);
}

vec3 Contrast(const vec3 color, const ColorCorrection m) {
	return LogContrast(color, m.contrast);
}

vec3 LiftGammaGain(const vec3 v, const ColorCorrection m) {
	vec3 lerpV = clamp01(pow(v, m.invGamma));
	return m.gain * lerpV + m.lift * (1.0 - lerpV);
}

#endif
