Implementing per-fragment spot light

We will now implement per-fragment spot light. Spot light is a special point light that emits light in a directional cone. The size of this cone is determined by the spot cutoff amount, which is given in angles, as shown in the following figure. In addition, the sharpness of the spot is controlled by the parameter spot exponent. A higher value of the exponent gives a sharper falloff and vice versa.

Implementing per-fragment spot light

Getting started

The code for this recipe is contained in the Chapter4/SpotLight directory. The vertex shader is the same as in the point light recipe. The fragment shader calculates the diffuse component, as in the Implementing per-vertex and per-fragment point lighting recipe.

How to do it…

Let us start this recipe by following these simple steps:

  1. From the light's object space position and spot light target's position, calculate the spot light direction vector in eye space.
    spotDirectionES  = glm::normalize(glm::vec3(MV*glm::vec4(spotPositionOS-lightPosOS,0)))
  2. In the fragment shader, calculate the diffuse component as in point light. In addition, calculate the spot effect by finding the angle between the light direction and the spot direction vector.
    vec3 L = (light_position.xyz-vEyeSpacePosition);
    float d = length(L);
    L = normalize(L);
    vec3 D = normalize(spot_direction);
    vec3 V = -L;
    float diffuse = 1;
    float spotEffect = dot(V,D);
  3. If the angle is greater than the spot cutoff, apply the spot exponent and then use the diffuse shader on the fragment.
    if(spotEffect > spot_cutoff) {
      spotEffect = pow(spotEffect, spot_exponent);
      diffuse = max(0, dot(vEyeSpaceNormal, L));
      float attenuationAmount = spotEffect/(k0 + (k1*d) + (k2*d*d));
      diffuse *= attenuationAmount;
      vFragColor = diffuse*vec4(diffuse_color,1);
    }

How it works…

The spot light is a special point light source that illuminates in a certain cone of direction. The amount of cone and the sharpness is controlled using the spot cutoff and spot exponent parameters respectively. Similar to the point light source, we first calculate the diffuse component. Instead of using the vector to light source (L) we use the opposite vector, which points in the direction of light (V=-L). Then we find out if the angle between the spot direction and the light direction vector is within the cutoff angle range. If it is, we apply the diffuse shading calculation. In addition, the sharpness of the spot light is controlled using the spot exponent parameter. This reduces the light in a falloff, giving a more pleasing spot light effect.

There's more…

The demo application implementing this recipe renders the same scene as in the point light demo. We can change the spot light direction using the right mouse button. The output result is shown in the following figure:

There's more…

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.1.136