#version 140 uniform sampler2D color; uniform sampler2D position; uniform sampler2D normal; uniform vec2 winSize; out vec4 fragColor; const int MAX_LIGHTS = 8; const int TYPE_POINT = 0; const int TYPE_DIRECTIONAL = 1; const int TYPE_SPOT = 2; struct Light { int type; vec3 position; vec3 color; float intensity; vec3 direction; float constantAttenuation; float linearAttenuation; float quadraticAttenuation; float cutOffAngle; }; uniform Light lights[MAX_LIGHTS]; uniform int lightCount; void main() { vec2 texCoord = gl_FragCoord.xy / winSize; vec4 col = texture(color, texCoord); vec3 pos = texture(position, texCoord).xyz; vec3 norm = texture(normal, texCoord).xyz; vec3 lightColor = vec3(0.0); vec3 s; for (int i = 0; i < lightCount; ++i) { float att = 1.0; if ( lights[i].type != TYPE_DIRECTIONAL ) { s = lights[i].position - pos; if (lights[i].constantAttenuation != 0.0 || lights[i].linearAttenuation != 0.0 || lights[i].quadraticAttenuation != 0.0) { float dist = length(s); att = 1.0 / (lights[i].constantAttenuation + lights[i].linearAttenuation * dist + lights[i].quadraticAttenuation * dist * dist); } s = normalize( s ); if ( lights[i].type == TYPE_SPOT ) { if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle) att = 0.0; } } else { s = normalize( -lights[i].direction ); } float diffuse = max( dot( s, norm ), 0.0 ); lightColor += att * lights[i].intensity * diffuse * lights[i].color; } fragColor = vec4(col.rgb * lightColor, col.a); }