// G buffer
uniform sampler2D gPosition;
uniform sampler2D gDiffuse;
uniform sampler2D gSpecular;
uniform sampler2D gNormal;
// Specularity info
uniform vec3 viewerPosition;
uniform float shininess;
uniform Light
{
vec3 position;
vec3 color;
float range;
float intensity;
} lightData[16];
uniform int numLights;
uniform vec3 lightAttenuation;
void main()
{
vec3 worldPos = texture2D(gPosition, gl_TexCoord[0].st).xyz;
vec3 worldNormal = texture2D(gNormal, gl_TexCoord[0].st).xyz;
vec3 sceneDiffuse = texture2D(gDiffuse, gl_TexCoord[0].st).rgb;
vec3 sceneSpecular = texture2D(gSpecular, gl_TexCoord[0].st).rgb;
vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0);
for(int i = 0; i < numLights; i++)
{
vec3 lightDir = lightData[i].position - worldPos;
float dist = length(lightDir);
float lightRange = lightData[i].range;
if(dist > lightRange)
continue;
lightDir /= dist;
float lambert = dot(lightDir, worldNormal);
if(lambert <= 0.0)
continue;
float fallOff = max(0.0, (lightRange - dist) / lightRange);
float attenuation = clamp(fallOff * lightData[i].intensity * (1.0 / (lightAttenuation.x + lightAttenuation.y * dist + lightAttenuation.z * dist * dist)), 0.0, 1.0);
// Specular
vec3 lightRay = reflect(normalize(-lightDir), worldNormal);
float specularIntensity = attenuation * pow(max(0.0, dot(lightRay, normalize(viewerPosition - worldPos))), shininess);
specularIntensity = max(0.0, specularIntensity);
finalColor += vec4(sceneDiffuse * attenuation * lambert * lightData[i].color + sceneSpecular * specularIntensity * lightData[i].color, 0.0);
}
gl_FragColor = finalColor;
}