#define SHADER_NAME PHASER_DEFERRED_DIFFUSE_FS

precision mediump float;

struct Light
{
    vec3 position;
    vec3 color;
    float attenuation;
    float radius;
};

const int kMaxLights = 50;

uniform vec4 uCamera; /* x, y, rotation, zoom */
uniform vec2 uResolution;
uniform sampler2D uMainSampler; // gbuffer color
uniform sampler2D uNormSampler; // gbuffer normal
uniform vec3 uAmbientLightColor;
uniform Light uLights[kMaxLights];

void main()
{
    vec2 uv = vec2(gl_FragCoord.xy / uResolution);
    vec3 finalColor = vec3(0.0, 0.0, 0.0);
    vec4 gbColor = texture2D(uMainSampler, uv);
    vec3 gbNormal = texture2D(uNormSampler, uv).rgb;
    vec3 normal = normalize(vec3(gbNormal * 2.0 - 1.0));
    vec2 res = vec2(min(uResolution.x, uResolution.y)) * uCamera.w;

    for (int index = 0; index < kMaxLights; ++index)
    {                
        Light light = uLights[index];
        vec3 lightDir = vec3((light.position.xy / res) - (gl_FragCoord.xy / res), light.position.z);
        vec3 lightNormal = normalize(lightDir);
        float distToSurf = length(lightDir) * uCamera.w;
        float diffuseFactor = max(dot(normal, lightNormal), 0.0);
        float radius = (light.radius / res.x * uCamera.w) * uCamera.w;
        float attenuation = clamp(1.0 - distToSurf * distToSurf / (radius * radius), 0.0, 1.0);
        vec3 diffuse = light.color * gbColor.rgb * diffuseFactor;
        finalColor += attenuation * diffuse;
    }

    vec4 colorOutput = vec4(uAmbientLightColor + finalColor, gbColor.a);
    gl_FragColor = colorOutput;
}