#version 440 in vec3 f_color; out vec4 FragColors; uniform vec3 Kd; uniform vec3 Ka; uniform vec3 Ks; uniform float Shininess; uniform vec4 LightLocation; uniform vec3 LightIntensity; uniform vec4 LightDirection; uniform float Exponent; uniform float Cutoff; uniform float InnerCutoff; in vec3 fNormal; in vec3 pos; const float a = 1.0f; const float b = 0.01f; const float c = 0.001f; void main() { vec3 LightDir = LightDirection.xyz - LightLocation.xyz; vec3 L = LightLocation.xyz - pos; float d = length(L); L = normalize(L); float attenuation = 1.0f / (a + b * d + c * pow(d, 2)); float angle = acos(dot(-L, normalize(LightDir))); // radian float spotAttenuation = 1.0f; if (angle < radians(InnerCutoff)) spotAttenuation = 1.0f; else { // pos is outside the spot's inner cutoff float SpotDot = dot(-L, normalize(LightDir)); float spotValue = smoothstep(cos(radians(Cutoff)), cos(radians(InnerCutoff)), SpotDot); spotAttenuation = pow(spotValue, Exponent); } attenuation *= spotAttenuation; vec3 N = normalize(fNormal); vec3 V = normalize(-pos); vec3 H = normalize(V + L); float dotNL = max(dot(L, N), 0.0); // for diffuse float dotHN = max(dot(H, N), 0.0); // for spec float pf = pow(dotHN, Shininess); // for spec vec3 ambient = Ka * LightIntensity * attenuation; vec3 diffuse = Kd * LightIntensity * dotNL * attenuation; vec3 specular = Ks * LightIntensity * pf * attenuation; FragColors = vec4(diffuse + specular + ambient, 1); }