Why do shadow maps take three passes?

I’m using a single shadow map in a forward renderer. I’d expect that this would take one additional pass to generate the shadow map. Instead there seems to be two extra passes. One to render the shadow map, and then one which seems to render the whole scene called “collect shadows”. That second pass seems redundant since the subsequent base pass rendering could just sample the shadow map directly.

Anyone know what’s wrong here? Is there a way to use a cheaper (standard) shadow mapping algorithm that doesn’t do the extra “collect shadows” pass over the objects?

Right, that’s how currently (Unity 2.0 - 4.3 at least) directional light shadowmaps work. More detail here: Deferred Cascaded Shadow Maps · Aras' website

But basically:

  1. render into the shadowmap cascades
  2. render objects into screenspace buffer, “collecting” the shadow term from the cascades.
  3. optionally blur that screenspace shadow mask
  4. in regular rendering, sample the screenspace shadows

Screenspace shadows have some advantages (less shader variants; just one tap to sample shadowmap) and some disadvantages (that extra rendering pass…).

We’re thinking about changing step 2 for the future however; instead of re-rendering the scene to get the result we’d compute screenspace shadowmap from the depth buffer.

I’m not 100% sure but I suspect that the second pass is computing a shadow overlay. That’s a screen-space texture that stores the amount of shadow at every point on the screen, sort of like the light buffer in deferred rendering, but for shadows. It can make scenes with a number of shadow casters and opaque shadow receivers much faster than it would be otherwise.