Directional light

Calculate light direction
We can just define a light direction in Light class
struct Light {
vec3 direction;
...
};
...
void main()
{
vec3 lightDir = normalize(-light.direction);
...
}
Point Light

Calculate Attenuation
reduce the intensity of light over the distance a light ray travels

struct Light {
float constant;
float linear;
float quadratic;
...
};
...
void main()
{
float distance = length(light.position - FragPos);
loat attenuation = 1.0 / (light.constant + light.linear * distance +
light.quadratic * (distance * distance));
...
}
Spot Light
We need: the spotlight’s position vector (to calculate the fragment-to-light’s direction vector), the spotlight’s direction vector and the cutoff angle.

Caculate Angles
We pass the cosine value because it is easier to compare

struct Light {
vec3 position;
vec3 direction;
float cutOff;
...
};
lightingShader.setFloat("light.cutOff", glm::cos(glm::radians(12.5f)));
calculate the theta θ value and compare this with the cutoff ϕ value to determine if we’re in or outside the spotlight:
if cosθ > cutOff, we can know that θ < ϕ
float theta = dot(lightDir, normalize(-light.direction));
if(theta > light.cutOff)
{
// do lighting calculations
}
else // else, use ambient light
color = vec4(light.ambient * vec3(texture(material.diffuse, TexCoords)), 1.0);
Smooth Edges
Set γ as outer cone angle value
intensity = (θ−γ) / (ϕ−γ)
float theta = dot(lightDir, normalize(-light.direction));
float epsilon = light.cutOff - light.outerCutOff;
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
...
// we'll leave ambient unaffected so we always have a little light.
diffuse *= intensity;
specular *= intensity;
...