uniform int useTexture; uniform sampler2D texSampler; uniform int numLights; uniform vec4 materialColor; uniform float shininess; uniform vec3 ambientLight; struct Light { vec4 vector; vec3 color; float intensity; float linear_att; }; uniform Light lights[10]; varying vec3 fcolor; varying vec2 ftexcoord; varying vec3 fnormal; varying vec4 fposition; void main() { vec3 diffuseAccum = vec3(0.0, 0.0, 0.0); vec3 specularAccum = vec3(0.0, 0.0, 0.0); if (numLights > 0) { diffuseAccum = ambientLight; for (int i = 0; i < 10; i++) { if (i >= numLights) break; vec3 N = normalize(fnormal); vec3 L = lights[i].vector.xyz; float attenuation = 1.0; if (lights[i].vector.w == 1.0) { L = L - fposition.xyz; float distance = length(L); attenuation = 1.0 / (1.0 + lights[i].linear_att * distance); } L = normalize(L); float NdotL = max(dot(N, L), 0.0); diffuseAccum += NdotL * lights[i].color * lights[i].intensity * attenuation; if (shininess > 0.0 && NdotL > 0.0) { vec3 V = normalize(-fposition.xyz); vec3 H = normalize(L + V); float NdotH = max(dot(N, H), 0.0); specularAccum += pow(NdotH, shininess) * attenuation * lights[i].color * lights[i].intensity; } } } vec4 fragmentColor; if (useTexture == 1) { fragmentColor = texture2D(texSampler, ftexcoord); } else { fragmentColor = materialColor; } if (numLights > 0) { gl_FragColor = vec4(fragmentColor.rgb * diffuseAccum + specularAccum, fragmentColor.a); } else { gl_FragColor = fragmentColor; } }