Adding special effects make our rendered scene more interesting. Shadows are one type of special effect. We show with this tutorial how to create a shadow on a plane.
Our method for creating this effect is to project onto a plane the geometry that casts the shadow with the current drawing color set to the desired shadow color. The projection is a transformation that we create. We represent our transformation with a 4x4 matrix much like the matrices created by OpenGL for any of the standard transformations including viewing transformation.
To compute the entries of our transformation matrix, we need the direction of the rays of light being "blocked" by the geometry and the equation of the plane on which the shadow is casted. We use in this tutorial a directional light as the source of illumination.
Recall that a directional light is established with a call such as
glLightfv(GL_LIGHT1, GL_POSITION,
position);
where position is a one-dimension array of four float values with the last value set to 0.0. Also we think of the first three values as the xyz coordinates of a point and the actual direction is from this point to the origin. For example, naming the first three values as Lx, Ly and Lz, the actual direction vector is (-Lx, -Ly, -Lz).
Now when a line (ray) parallel to the above direction vector passes through a point P in the geometry, the light is blocked by the geometry and the shadow occurs at the intersection of the line and the plane. We use the parametric equations of the line to calculate the point of intersection. Letting (Px, Py, Pz) be the coordinates of a point in the geometry, we have the following parametric equations.
x = -t*Lx + Px y = -t*Ly + Py z = -t*Lz + PzThe easiest situation for finding the point of intersection is when the plane is one of the coordinate planes. Using the xz-plane, we have y = 0 as its equation. Thus, setting y equal to zero in the second parametric equation and solving for t, we have
t = Py/LyNext, setting this value for t in the other two equations gives us the coordinates of the projection point, namely,
x = -(Py/Ly)*Lx + Px = -(Lx/Ly)*Py + Px y = 0 z = -(Py/Ly)*Lz + Pz = -(Lz/Ly)*Py + PzLast, we construct the 4x4 matrix that is applied to the homogeneous coordinates (Px, Py, Pz, 1) and produces the above projection point. The entries of the matrix are as follows:
1.0 -(Lx/Ly) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -(Lz/Ly) 1.0 0.0 0.0 0.0 0.0 1.0We perform a similar process to obtain the projection matrix for each of the other two coordinate planes. As a final note, if you find that the projected geometry is obsured somewhat by the geometry of the plane due to depth testing, then you may try moving the projected geometry away from the plane by a small amount. If, for example, the plane is the xz coordinate plane, then try 0.05 instead of 0.0 as the entry in the second row, second column.