sampler texture0 : register(s0);

float4x4 WorldViewProjectionTransform  : WORLDVIEWPROJ;
float2 fTextureSize;
float fSaturation;
float fContrast;
float fBrightness;
float fGamma;

struct VS_OUTPUT 
{
   float4 Position  : POSITION;
   float2 TexCoord  : TEXCOORD0;    
};

struct PS_OUTPUT
{
    float4 RGBColor : COLOR0;  // Pixel color    
};

VS_OUTPUT vertexMain(
				float4 vPosition : POSITION,
				float2 texCoord0 : TEXCOORD0)
{
	VS_OUTPUT Output; 

	Output.Position = mul(vPosition, WorldViewProjectionTransform);
	Output.TexCoord = texCoord0;   

	return Output;
}

PS_OUTPUT pixelMain(VS_OUTPUT In)
{
	float fInSaturation = fSaturation + 1.f;
	float fInGamma = fGamma + 1.f;

	float2 coord = In.TexCoord + 1.f / fTextureSize / 2.f;
	float4 color = tex2D(texture0, coord);

	float tmpFactor = step(fContrast, 0.f);
	float tmpFactorInv = 1.f - tmpFactor;
	float fFactor = (1.f / (1.01f - fContrast)) * tmpFactor + (1.f + fContrast) * tmpFactorInv;

	float fOffset = fBrightness * 0.5f;
	fOffset -= fFactor * 0.5f;
	fOffset += 0.5;

	float fInverseGamma = 1.f / fInGamma;
	color = saturate(color * fFactor + fOffset);
	color = saturate(pow(color, fInverseGamma));

	// saturation
	float fIntensity = (0.114f * color.b + 0.587f * color.g + 0.299f * color.r);
	float4 intensityColor = {fIntensity, fIntensity, fIntensity, color.a};
	float4 saturation = {fInSaturation, fInSaturation, fInSaturation, 0.0f};
	color = saturate(lerp(intensityColor, color, saturation));

	PS_OUTPUT output;
	output.RGBColor = color;
	return output;
}