#version 450
layout(location = 0) in vec3  vNormal;
layout(location = 1) in vec4  vColor;
layout(location = 2) in float vDist;
layout(location = 3) in vec3  vWorld;

layout(std140, binding = 0) uniform Globals {
    mat4  uMVP;
    mat4  uModel;
    vec3  uCamPos;
    float uLight;
    vec3  uFog;
    float uFogStart;
    float uFogEnd;
    vec4  uTint;
    float uFlash;
    int   uDynLightCount;
    vec4  uDynLightPosRadius0;
    vec4  uDynLightPosRadius1;
    vec4  uDynLightPosRadius2;
    vec4  uDynLightPosRadius3;
    vec4  uDynLightColor0;
    vec4  uDynLightColor1;
    vec4  uDynLightColor2;
    vec4  uDynLightColor3;
};

layout(location = 0) out vec4 FragColor;

vec3 pointLight(vec3 p, vec4 posRadius, vec4 colorIntensity) {
    vec3 d = p - posRadius.xyz;
    float a = max(0.0, 1.0 - dot(d, d) / max(posRadius.w * posRadius.w, 0.001));
    return colorIntensity.rgb * (colorIntensity.a * a * a);
}

vec3 dynamicLighting(vec3 p) {
    vec3 l = vec3(0.0);
    if (uDynLightCount > 0) l += pointLight(p, uDynLightPosRadius0, uDynLightColor0);
    if (uDynLightCount > 1) l += pointLight(p, uDynLightPosRadius1, uDynLightColor1);
    if (uDynLightCount > 2) l += pointLight(p, uDynLightPosRadius2, uDynLightColor2);
    if (uDynLightCount > 3) l += pointLight(p, uDynLightPosRadius3, uDynLightColor3);
    return min(l, vec3(2.0));
}

void main() {
    vec3 N = normalize(vNormal);
    float lambert = 0.5 + 0.5 * max(dot(N, normalize(vec3(0.4, 1.0, 0.3))), 0.0);
    vec3 c = vColor.rgb * uTint.rgb * lambert * uLight;
    if (uDynLightCount > 0) {
        vec3 dyn = dynamicLighting(vWorld);
        c = max(c, vColor.rgb * uTint.rgb * lambert * dyn);
        c += vColor.rgb * uTint.rgb * lambert * dyn * 0.08;
    }
    c = mix(c, vec3(1.0), uFlash);
    float fog = clamp((vDist - uFogStart) / max(1.0, uFogEnd - uFogStart), 0.0, 1.0);
    c = mix(c, uFog, fog);
    FragColor = vec4(c, vColor.a * uTint.a);
}
