#version 330

uniform vec3 uSunDirection = vec3(0.0, 1.0, 0.0); // pointing towards the sun
uniform vec3 uSunColor = vec3(1.0);
uniform vec3 uAmbientLightColor = vec3(0.3);

uniform bool uShadowsEnabled = false;
uniform mat4 uSunMatrix;
uniform sampler2DRect uSunShadow;

// Shadow map is only defined within this box
uniform vec3 uShadowMin;
uniform vec3 uShadowMax;

vec3 sunLighting(vec3 pos, vec3 normal, vec3 cameraPos, vec3 diffuseColor, float specularIntensity)
{
    vec3 eyeDir   = normalize(cameraPos - pos);
    vec3 halfVector = normalize(eyeDir + uSunDirection);

    float lambertian = max(dot(uSunDirection, normal), 0.0);
    float specular = pow(max(dot(halfVector, normal), 0.0), 48.0);

    vec3 color = uAmbientLightColor * diffuseColor;

    // shadow
    float shadow = 1.0;
    if(uShadowsEnabled)
    {
        vec4 sunPos = uSunMatrix * vec4(pos, 1.0);
        vec2 sunAbs = (sunPos.xy * .5 + .5) * 2048;
        float sunZ = texture(uSunShadow, sunAbs).r;
        float refZ = exp(-80.f * (sunPos.z+1)/2.0);
        shadow = clamp(refZ * sunZ, 0.0, 1.0);

        if(any(greaterThan(abs(sunPos.xyz), vec3(1.0))))
            shadow = 1.0;
    }

    color += shadow * lambertian * uSunColor * diffuseColor; // diffuse
    color += shadow * specularIntensity * specular * uSunColor; // specular

    return color;
}
