Shadow maps use the depth buffer and projective texture mapping to create a screen space method for shadowing objects [84,92]. Its performance is not directly dependent on the complexity of the shadowing object.
The scene is transformed so that the eye point is at the light source. The objects in the scene are rendered, updating the depth buffer. The depth buffer is read back, then written into a texture map. This texture is mapped onto the primitives in the original scene, as viewed from the eye point, using the texture transformation matrix, and eye space texture coordinate generation. The value of the texture's texel value, the texture's ``intensity'', is compared against the texture coordinate's value at each pixel. This comparison is used to determine whether the pixel is shadowed from the light source. If the value of the texture coordinate is greater than texel value, the object was in shadow. If not, it was lit by the light in question.
This procedure works because the depth buffer records the distances from the light to every object in the scene, creating a shadow map. The smaller the value, the closer the object is to the light. The transform and texture coordinate generation is chosen so that , , and locations of objects in the scene map to the and coordinates of the proper texels in the shadow texture map, and to values corresponding to the distance from the light source. Note that the values and texel values must be scaled so that comparisons between them are meaningful.
Both values measure the distance from an object to the light. The texel value is the distance between the light and the first object encountered along that texel's path. If the distance is greater than the texel value, this means that there is an object closer to the light than this one. Otherwise, there is nothing closer to the light than this object, so it is illuminated by the light source. Think of it as a depth test done from the light's point of view.
Shadow maps can almost be done with the OpenGL 1.1 implementation. However, the ability to compare the texture's r component against the corresponding texel value is missing. There is an OpenGL extension, SGIX_shadow, that performs the comparison. As each texel is compared, the results set the fragment's alpha value to 0 or 1. The extension can be described as using the shadow texture value test to mask out shadowed areas using alpha values.
The ARB_multitexture extension to OpenGL 1.2 and EXT_texture_env_combine may be used on some implementations to perform the shadow map depth comparison in the texure environment, but the source textures are limited to the alpha or luminance component sizes, currently 8 bits on available accelerators. Using stencil or destination alpha, multipass techniques can be used to extend the shadow map precision to multiples of the component size.