63 lines
1.5 KiB
GLSL

#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);
}