#version 450

layout (location = 0) in vec3 vertexViewSpacePosition;
layout (location = 1) in vec2 vertexTexCoords;

layout (location = 0) out vec4 fragLight;

layout (binding = 0) uniform sampler2D albedo;                ///< g-buffer colors
layout (binding = 1) uniform sampler2D worldSpacePositionMap; ///< vertex position in world-space
layout (binding = 2) uniform sampler2D viewSpacePositionMap;  ///< vertex position in view-space
layout (binding = 3) uniform sampler2D normalMap;             ///< vertex normal in view-space
layout (binding = 4) uniform sampler2DShadow shadowMap;       ///< shadow map

uniform mat4 viewMatrix;   // From world-space to camera view-space
uniform mat4 shadowMatrix; // From world-space to shadowCamera view-space

uniform vec3 light_color;
uniform float light_intensity;
uniform vec3 light_direction;

vec3 directionalLightADS(vec3 viewSpaceDirection,
                         vec3 viewSpaceNormal,
                         vec3 viewSpaceObjectPosition,
                         vec3 color,
                         float intensity)
{
    // Lighting
    float Li = intensity;
    vec3 Ka = vec3(0.2);
    vec3 Kd = color;
    vec3 Ks = vec3(0.5);
    float shininess = 10;
    
    vec3 n = viewSpaceNormal;
    vec3 s = viewSpaceDirection;
    vec3 v = normalize(-vec3(viewSpaceObjectPosition));
    vec3 h = normalize(v + s);
    
    vec3 pixelLight = vec3((0.2) + Li) * 
                      ((Kd) * max(dot(s, n), 0.0) +
                       (Ks) * pow(max(dot(h, n), 0.0), shininess));
    // Final color
    return pixelLight;
}

vec4 getShadow(vec3 a, vec3 ds)
{
    vec4 wp = texture(worldSpacePositionMap, vertexTexCoords);
    vec4 shadowCoord = shadowMatrix * wp;
    
    float visibility = 1.0;
    if(shadowCoord.z >= 0 ) {
//        vec4 normalTexel = texture(normalMap, vertexTexCoords);
//        float bias = max(0.05 * (1.0 - dot(normalTexel.xyz, light_direction)), 0.005);
//        visibility = textureProj(shadowMap, vec4(shadowCoord.xy, shadowCoord.z-bias, shadowCoord.w), bias);
//        shadowCoord.z -= bias;
        visibility = textureProj(shadowMap, shadowCoord);
    }
        
    return vec4(a + ds * visibility, 1.0);
}

void main()
{
    // Get texels
    vec4 positionTexel = texture(viewSpacePositionMap, vertexTexCoords);
    vec4 normalTexel = texture(normalMap, vertexTexCoords);
    
    // Lighting calc
    vec3 a = vec3(0.2);
    vec3 ds = directionalLightADS(normalize(viewMatrix * vec4(light_direction, 0)).xyz,
                                  normalTexel.xyz,
                                  positionTexel.xyz,
                                  light_color,
                                  light_intensity);

    fragLight = vec4(a + ds, 1);//getShadow(a, ds);
//    fragLight = getShadow(a, ds);
}
