#ifdef GL_ES
precision mediump float;
#endif

uniform sampler2D u_texture;
uniform sampler2D u_heightmapTexture;
uniform sampler2D u_lightmapTexture;
uniform vec2 u_resolution;

uniform int u_lightCount;
uniform float u_lightFalloffs[8];
uniform vec2 u_lightPositions[8];
uniform vec4 u_lightColors[8];
uniform vec2 u_cameraScale;


/**
 * PLAY AROUND WITH THESE
 */

// color of "HDR" bright pixels
const vec4 highlightLight = vec4(1.0, 0.95, 0.9, 1.0);
// black pixels are greyscaled and then tinted to this color
const vec4 ambientLight = vec4(0.15, 0.1, 0.175, 1.0);
// adjust the brightness of mid-level (tinted) pixels
const float midBrightness = 0.5;
// how much to blend the highlight color with the source color
const float highlightAmount = 0.8;
// how much to tint bright pixels with the lightmap color
const float tintAmount = 0.5;

// weight of the lightmap in determining pixel lighting level
const float lightmapMultiplier = 1.0;
// weight of the heightmap in determining pixel lighting level
const float heightmapMultiplier = 0.35;

// if light value is over this, use highlight color
const float highlightThreshold = 1.34;
// if light value is over this, use original pixel color
const float brightThreshold = 0.6;
// if light value is over this, use tinted color multiplied with midBrightness
const float darkThreshold = 0.35;
// otherwise tint with ambientLight

// two color areas will be blended within this range in either direction of each other so we get smoother edges
// this value needs to be less than the difference between any of the thresholds
//const float smoothAmount = 0.0075;
const float smoothAmount = 0.005;

/**
 * OK STOP PLAYING AROUND
 */

varying vec2 v_texCoord;
varying vec4 v_color;

vec4 greyscale(in vec4 color, in float level) {
	float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));

	return mix(color, vec4(gray, gray, gray, color.a), level);
}

void main() {
	vec2 texCoord = vec2(gl_FragCoord.x / u_resolution.x, gl_FragCoord.y / u_resolution.y);
	vec4 color = texture2D(u_texture, texCoord);

	vec2 glCoord = vec2(gl_FragCoord);

	vec4 heightmapColor = texture2D(u_heightmapTexture, texCoord);
	vec4 lightmapColor = texture2D(u_lightmapTexture, texCoord);

	float heightmapBrightness = (heightmapColor[0] + heightmapColor[1] + heightmapColor[2]) / 3.0;
	float lightmapBrightness = (lightmapColor[0] + lightmapColor[1] + lightmapColor[2]) / 3.0;
	float brightness = lightmapBrightness * lightmapMultiplier + heightmapBrightness * heightmapMultiplier;

	vec4 highlightColor = mix(color, highlightLight, highlightAmount);
	vec4 tintedColor = mix(color, color*(lightmapColor/lightmapBrightness), tintAmount);
	vec4 midColor = color * (lightmapColor/lightmapBrightness) * midBrightness;
	vec4 ambientColor = greyscale(color, 1.0) * ambientLight;;

	// use highlight color
	if (brightness > highlightThreshold + smoothAmount) {
		gl_FragColor = highlightColor;
	} else if (brightness > highlightThreshold - smoothAmount) {
		gl_FragColor = mix(tintedColor, highlightColor, (brightness - highlightThreshold + smoothAmount) / (smoothAmount));
	// use tinted color
	} else if (brightness > brightThreshold) {
		gl_FragColor = tintedColor;
	} else if (brightness > brightThreshold - smoothAmount) {
		gl_FragColor = mix(midColor, tintedColor, (brightness - brightThreshold + smoothAmount) / (smoothAmount));
	// use mid color
	} else if (brightness > darkThreshold) {
		gl_FragColor = midColor;
	} else if (brightness > darkThreshold - smoothAmount) {
		gl_FragColor = mix(ambientColor, midColor, (brightness - darkThreshold + smoothAmount) / (smoothAmount));
	// ambient
	} else {
		gl_FragColor = ambientColor;
	}
}