Step 1: render the scene from the light's point of view (without
calculating light, color or any other shading process).
Step 2: extract and save (usually in a texture) the depth buffer from
the rendering (z-buffer generated by the projection process).
This texture is called shadow map. If there are multiple lights, a separate
depth map must be used for each light.
Step 3: perform a normal rendering pass, and when evaluating
whether a fragment is visible to the light source, project its location in
the shadow map and compare the looked-up value dmap with the
actual distance d to the light source.
If the distances are the same, the fragment’s point is illuminated; if the d > dmap,
that implies there is a different surface closer to the source, so it is shadowed.