Help end child hunger

GLSL Core Tutorial – Spotlights

Prev: Point Lights Next: Texture Coordinates

Spotlights are restricted point lights, i.e.  the light rays are only emitted in a restricted set of directions. Commonly we use a cone to define this restriction, but other shapes are possible.

The following diagram shows a cone shaped spotlight and the relevant data.


  • position: this is the cone’s apex (sp);
  • spot direction: the vector that defines the direction of the axis of the cone (sd);
  • cutoff angle: the aperture of the cone. In here we are going to assume that the angle is measured from the direction vector to the border of the cone (\alpha ).

The vertex shader is the same as for point lights. It is up to the fragment shader to determine if a fragment is inside the cone, i.e. the dot product between the light’s direction and the spot’s direction is less than some cutoff value, and lit it accordingly. Actually, instead of using an angle, we should provide the cosine of the angle to avoid having to compute the inverse cosine in a shader.

#version 330

out vec4 colorOut;

layout (std140) uniform Materials {
	vec4 diffuse;
	vec4 ambient;
	vec4 specular;
	float shininess;

layout (std140) uniform Lights {
	vec4 l_pos, l_spotDir;
	float l_spotCutOff;

in Data {
	vec3 normal;
	vec3 eye;
	vec3 lightDir;
} DataIn;

void main() {

	float intensity = 0.0;
	vec4 spec = vec4(0.0);

	vec3 ld = normalize(DataIn.lightDir);
	vec3 sd = normalize(vec3(-l_spotDir));	

	// inside the cone?
	if (dot(sd,ld) > l_spotCutOff) {

		vec3 n = normalize(DataIn.normal);
		intensity = max(dot(n,ld), 0.0);

		if (intensity > 0.0) {
			vec3 eye = normalize(DataIn.eye);
			vec3 h = normalize(ld + eye);
			float intSpec = max(dot(h,n), 0.0);
			spec = specular * pow(intSpec, shininess);

	colorOut = max(intensity * diffuse + spec, ambient);

An example image is presented below.



Prev: Point Lights Next: Texture Coordinates
© 2014 Suffusion theme by Sayontan Sinha