// Copyright (C) Kimmo Lahtinen - All Rights Reserved

// Input from vertex shader
varying vec2 frag_light_texture_uv;
varying vec2 frag_mesh_pos;
varying vec2 frag_shadow_map_uv;
varying float frag_depth;
varying vec3 frag_color;

uniform sampler2D uni_texture_diffuse;
uniform sampler2D uni_texture_shadow_map;

///////////////////////////////////////////////////////////////////////////////
// Supported quality macros, #defined in common.vert!

// Smooth light angling (no ugly warping because of per vertex calculation), but requires dependent texture read
// Note: Requires dependent anyway if any blurring is enabled
//#define LIGHT_SHADOW_SMOOTH_ANGLE

// Blur the shadow edges with a few samples
//#define LIGHT_SHADOW_BLUR_RADIAL

// If blurring shadow edges, use a large number of samples + gaussian 
//#define LIGHT_SHADOW_BLUR_MODE_GAUSSIAN

///////////////////////////////////////////////////////////////////////////////

float calculate_depth_alpha(vec2 shadow_texture_uv)
{
	vec4 shadow_depth = texture2D(uni_texture_shadow_map, shadow_texture_uv);

// Do small fade at the beginning of shadow to hide the sharp edge depth wise
#define BLUR_DEPTH

#ifdef BLUR_DEPTH
	const float step_range = 0.04;
	float a = smoothstep(-step_range, step_range, (shadow_depth.r * 0.5) - frag_depth);
#else	
	float a = step(0.0, (shadow_depth.r * 0.5) - frag_depth);
#endif

	return a;
}

void main(void) 
{
	vec2 shadow_map_uv = frag_shadow_map_uv;
#ifdef LIGHT_SHADOW_SMOOTH_ANGLE
	shadow_map_uv.x = (atan(frag_mesh_pos.y, frag_mesh_pos.x) + UU_PI) / UU_PI_TWO;
#endif

#ifdef LIGHT_SHADOW_BLUR_RADIAL
	// Do depth test for neighbours too and interpolate... very SLOW for iOS!

#ifdef LIGHT_SHADOW_BLUR_MODE_GAUSSIAN
	// Gaussian blur test
	const mediump float weight_0 = 0.2270270270;
	const mediump float weight_1 = 0.1945945946;
	const mediump float weight_2 = 0.1216216216;
	const mediump float weight_3 = 0.0540540541;
	const mediump float weight_4 = 0.0162162162;

	mediump vec2 blur_step = vec2(0.0035, 0);
	mediump float a = 0.0;
	a += calculate_depth_alpha(shadow_map_uv  - 4.0 * blur_step) * weight_4;
	a += calculate_depth_alpha(shadow_map_uv  - 3.0 * blur_step) * weight_3;
	a += calculate_depth_alpha(shadow_map_uv  - 2.0 * blur_step) * weight_2;
	a += calculate_depth_alpha(shadow_map_uv  -       blur_step) * weight_1;
	a += calculate_depth_alpha(shadow_map_uv                   ) * weight_0;
	a += calculate_depth_alpha(shadow_map_uv  +       blur_step) * weight_1;
	a += calculate_depth_alpha(shadow_map_uv  + 2.0 * blur_step) * weight_2;
	a += calculate_depth_alpha(shadow_map_uv  + 3.0 * blur_step) * weight_3;
	a += calculate_depth_alpha(shadow_map_uv  + 4.0 * blur_step) * weight_4;
#else
	mediump vec2 offset_step = vec2(0.0045, 0);
	mediump float a = 
		calculate_depth_alpha(shadow_map_uv - offset_step) 	* 0.27901 +
		calculate_depth_alpha(shadow_map_uv) 				* 0.44198 +
		calculate_depth_alpha(shadow_map_uv + offset_step)	* 0.27901;
#endif		
#else
	mediump float a = calculate_depth_alpha(shadow_map_uv);
#endif

	// Note: this is premultiplied alpha, take care if doing something fancy
	lowp vec3 texture_color = texture2D(uni_texture_diffuse, frag_light_texture_uv).rgb;
	gl_FragColor.rgb = texture_color * frag_color * (a * LIGHTMAP_COLOR_WRITE_FACTOR);

//	gl_FragColor.rgb *= 0.0001;
//	gl_FragColor.rgb += frag_depth;
//	gl_FragColor.rgb += shadow_map_uv.x;

	gl_FragColor.a = 0.0;
}
