Revision control

++ #version 110
++
++ uniform sampler2D color;
++ uniform sampler2D position;
++ uniform sampler2D normal;
++ uniform vec2 winSize;
++
++ 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 = texture2D(color, texCoord);
++ vec3 pos = texture2D(position, texCoord).xyz;
++ vec3 norm = texture2D(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;
++ }
++ gl_FragColor = vec4(col.rgb * lightColor, col.a);
++ }