varying vec4 shadowCoord;
varying vec3 normal;

uniform sampler2D diffuseMap;
uniform sampler2DShadow shadowMap;
uniform float shadowMapSize;

float shadowLookup(sampler2DShadow depths, vec4 coord, vec2 offset)
{
    float texelSize = 1.0 / shadowMapSize;
    vec2 v = offset * texelSize * coord.w;
    float z = shadow2DProj(depths, coord + vec4(v.x, v.y, 0.0, 0.0)).z;
    return z;
}

float pcf(sampler2DShadow depths, vec4 coord, float radius)
{
    float s = 0.0;
    float x, y;
	for (y = -radius ; y < radius ; y += 1.0)
	for (x = -radius ; x < radius ; x += 1.0)
    {
	    s += shadowLookup(depths, coord, vec2(x, y));
    }
	s /= radius * radius * 4.0;
    return s;
}

float weight(vec4 tc)
{
    vec2 proj = vec2(tc.x / tc.w, tc.y / tc.w);
    proj = (1.0 - abs(proj * 2.0 - 1.0)) * 8.0;
    proj = clamp(proj, 0.0, 1.0);
    return min(proj.x, proj.y);
}

void main()
{    
    vec3 directionToLight = normalize(gl_LightSource[0].position.xyz);
    vec3 N = normalize(normal);
    float diffuse = clamp(dot(N, directionToLight), 0.0, 1.0);
    
    vec4 diffuseCol = texture2D(diffuseMap, gl_TexCoord[0].st);

    float s1 = pcf(shadowMap, shadowCoord, 3.0);
    float w1 = weight(shadowCoord);
    float shadow = mix(1.0, s1, w1);

    gl_FragColor = diffuseCol * 0.3 + diffuseCol * diffuse * shadow;
    gl_FragColor.a = diffuseCol.a;
}
