/** * OpenGL RedBook Shader. * Examples 7.8, 7.9 and 7.10. */ #version 330 core struct LightProperties { bool isEnabled; bool isLocal; bool isSpot; vec3 ambient; vec3 colour; vec3 position; vec3 halfVector; vec3 coneDirection; float spotCosCustoff; float spotExponent; float constantAttenuation; float linearAttenuation; float quadraticAttenuation; }; // example 7.9 struct MaterialProperties { vec3 emission; vec3 ambient; vec3 diffuse; vec3 specular; float shininess; }; const int MaxLights = 8; uniform LightProperties lights[MaxLights]; const int MaxMaterials = 1; uniform MaterialProperties materials[MaxMaterials]; uniform float Strength; uniform vec3 EyeDirection; in vec4 Position; in vec3 Normal; in vec4 Colour; flat in int MatIndex; out vec4 FragColour; void main() { vec3 scatteredLight = vec3(0.0); vec3 reflectedLight = vec3(0.0); for(int light = 0; light < MaxLights; ++light) { if ( !lights[light].isEnabled ) continue; vec3 halfVector; vec3 lightDirection = lights[light].position; float attenuation = 1.0; float specular = 0; if ( lights[light].isLocal ) { lightDirection = lightDirection - vec3(Position); float lightDistance = length(lightDirection); lightDirection = lightDirection / lightDistance; attenuation = 1.0 / lights[light].constantAttenuation + lights[light].linearAttenuation * lightDistance + lights[light].quadraticAttenuation * lightDistance * lightDistance; if ( lights[light].isSpot ) { float spotCos = dot(lightDirection, -lights[light].coneDirection); if ( spotCos < lights[light].spotCosCustoff ) attenuation = 0.0; else attenuation *= pow(spotCos, lights[light].spotExponent); } halfVector = normalize(lightDirection + EyeDirection); specular = max(0.0, dot(Normal, halfVector)); } else { //halfVector = lights[light].halfVector; halfVector = reflect(-lightDirection, Normal); specular = max(0.0, dot(EyeDirection, halfVector)); } float diffuse = max(0.0, dot(Normal, lightDirection)); if (diffuse == 0.0) specular = 0.0; else specular = pow(specular, materials[MatIndex].shininess) * Strength; scatteredLight += lights[light].ambient * materials[MatIndex].ambient * attenuation + lights[light].colour * materials[MatIndex].diffuse * diffuse * attenuation; reflectedLight += lights[light].colour * materials[MatIndex].specular * specular * attenuation; } vec3 rgb = min( materials[MatIndex].emission + Colour.rgb * scatteredLight + reflectedLight, vec3(1.0)); FragColour = vec4(rgb, 1.0); }