#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 albedoMap;                ///< 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 float light_attenuation;
uniform vec3 light_position;

vec3 pointLightADS(vec4 diffuseTexel,
                   vec3 positionTexel,
                   vec3 NormalTexel)
{
    // Light position
    vec3 light_position_viewSpace = (viewMatrix * vec4(light_position, 1)).xyz;

    // Lighting
    vec3 Lp = light_position_viewSpace;
    float Li = light_intensity;
    vec3 Ka = vec3(0.0);
    vec3 Kd = light_color;
    vec3 Ks = vec3(0.5);
    float shininess = 10;
    vec3 n = normalize(NormalTexel);
    vec3 s = normalize(vec3(Lp) - positionTexel);
    vec3 v = normalize(vec3(-positionTexel));
    vec3 h = normalize(v + s);

    float attentuationFactor = light_attenuation;
    float distanceToLight = length(Lp.xyz - positionTexel.xyz);
    float attenuation = 1.0 / (1.0 + attentuationFactor * pow(distanceToLight, 2));

    vec3 pixelLight = vec3(Li * (Ka * diffuseTexel.rgb) +
                           attenuation *
                           ((Kd * diffuseTexel.rgb) * max(dot(s, n), 0.0) +
                            (Ks * diffuseTexel.rgb) * pow(max(dot(h, n), 0.0), shininess)));
    
    // Final color
    return pixelLight;
}

void main()
{    
    // Lighting calc
    vec3 a = vec3(0.0);
    vec3 ds = pointLightADS(texture(albedoMap, vertexTexCoords), 
                            texture(viewSpacePositionMap, vertexTexCoords).xyz, 
                            texture(normalMap, vertexTexCoords).xyz);

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