uniform sampler2D s_tex0; 

uniform float luminance;
uniform float averageLuminance;
uniform float daytime;
uniform float factor;
uniform float noise;
uniform float time;
uniform vec3 colorShift;

uniform vec4 u_blendcolor;

varying vec2 v_texcoord;

const float KEY = 0.36;
const float FUDGE = 0.001;
const float L_WHITE = 0.5;
const float L_WHITE_SQUARED = L_WHITE * L_WHITE;
const float PI = 3.14159265358979323846264;
const float RECOVERY_SATURATION = 1.0;

// from: http://www.koders.com/noncode/fidB134383CDA66ACFDDE1E2BB70579CB362DC28D24.aspx
vec3 reinhardToneMap(in vec3 inColour, in float averageLuminance)
{
	//make sure we don't have any 0s ('singularities at black')
	// inColour += FUDGE;
	
	// From Reinhard et al
	// "Photographic Tone Reproduction for Digital Images"
	
	//compute luminance of current color (http://www.cs.bris.ac.uk/~reinhard/papers/jgt_reinhard.pdf)
	float worldLuminance = 0.27 * inColour.r + 0.67 * inColour.g + 0.06 * inColour.b;
	// Initial luminence scaling (equation 2)
	float scaledLuminance = KEY / averageLuminance  * worldLuminance;
	
	//bring ALL luminance into displayable range (equation 3)...
	// float displayLuminance = scaledLuminance / (1 + scaledLuminance);
	
	// ...or allow some burning or white out. controlled by L_WHITE (equation 4 nom)
	float displayLuminance = scaledLuminance * (1.0 + scaledLuminance / L_WHITE_SQUARED);
	// Final mapping (equation 4 denom)
	displayLuminance /= (1.0 + scaledLuminance);
	
	//recover RGB values (http://www.cs.virginia.edu/~gfx/pubs/tonemapGPU/itm.pdf)
	inColour.r = pow((inColour.r/worldLuminance),RECOVERY_SATURATION) * displayLuminance;
	inColour.g = pow((inColour.g/worldLuminance),RECOVERY_SATURATION) * displayLuminance;
	inColour.b = pow((inColour.b/worldLuminance),RECOVERY_SATURATION) * displayLuminance;
	
	return inColour;
}

float rand(vec2 co){
    return fract(sin(dot(co.xy ,vec2(1.29898,.78233))) * 43758.5453);
}

vec3 tint(in vec3 color)
{
	//exposure + gamma
	color.rgb = color.rgb * luminance;
	// color.r = pow(color.r, 1.0/averageLuminance);
	// color.g = pow(color.g, 1.0/averageLuminance);
	// color.b = pow(color.b, 1.0/averageLuminance);
	
	//uniform luminance
	// float curLum = 0.27 * color.r + 0.67 * color.g + 0.06 * color.b;
	// float relLumFactor = luminance/curLum;
	// 
	// color.rgb *= relLumFactor;

	return reinhardToneMap(color, averageLuminance);
//	return clamp(color.rgb, 0.0, 1.0);
}

void main()
{	
	vec4 color = texture2D(s_tex0, v_texcoord) * u_blendcolor;

	// color.rgb += rand(v_texcoord.xy*time) * (1.0-daytime) * factor * noise;
	color.rgb  = (1.-factor) * color.rgb + factor * tint(color.rgb);

	gl_FragColor = color;
}
