Right now when culling the models to render for the directional light shadow map pass I just do a view frustrum culling using the main camera. At some angles, the objects will be outside the view but still obviously should cast shadows.

My question is, how do you cull/gather all the relevant shadow casters for a directional light?


2 Answers 2


There is an advanced technology based on compute shaders that will analyze the depth buffer of the main camera, and return the min depth, and max depth, with 1 pixel precision (reduce operation). This information can be used to create a very precise frustum for the shadow camera. Elements outside the view that casts shadows are only in the frustum that goes from the viewed zone to the light. (oblique in the direction of the lighting).

shadow volume

One issue with this is that you don't know the min/max before rendering the world, and you need the shadow map to render the world. So to palliate to that, you can simply use a min/max pair that is one frame late. And to mitigate potential little artefacts if the player moves too fast, you can inflate the volume slightly by some epsilon.

  • \$\begingroup\$ I am using depth reduction through SDSM already, so I have the min/max depth. What I dont understand is, what do you use to test if the models are casting shadows or not? \$\endgroup\$ Commented May 12, 2015 at 8:25
  • \$\begingroup\$ Your question is puzzling in the sense that you should naturally think that every existing solid casts shadow, end of story. therefore your rendering volume (==the shadow camera view matrix), should incorporate everything, which is on its coarsest, the whole scene. For quality (and performance as a bonus), it is best to shrink the volume like schematized above. You won't be missing casters FOR SURE because you shrink orthogonaly to the light direction. \$\endgroup\$
    – v.oddou
    Commented May 12, 2015 at 8:57
  • \$\begingroup\$ @KaiserJohaan My guess is you are having fears of losing casters because you think of shrinking the volume longitudinally (in the direction of the light). This is something you are indeed not allowed to do, or you risk (and will), lose shadow casters. That is why the schema says "found from scene AABB". This tells you that the extreme global world limit is used, and it does not depend on view. Which is how you ensure all potential casters will be included. \$\endgroup\$
    – v.oddou
    Commented May 12, 2015 at 8:59
  • \$\begingroup\$ The shadow cam frustrum is an orthogonal projection matrix that is then rotated towards the light direction? If so how do you create such a matrix? And what would the shadow cam far plane be? \$\endgroup\$ Commented May 12, 2015 at 13:38
  • \$\begingroup\$ Also if that is the same camera used when rendering the shadow map, wouldn't it possibly loose alot of resolution, if the near plane is scene aabb and there might alot of empty space between the near plane and the first object? \$\endgroup\$ Commented May 12, 2015 at 13:49

I don't do a frustum cull with the main camera, but the shadow camera alone.

I calculate the AABB (axis aligned bounding box) of the shadow camera, then do the culling with that. A directional shadow camera is a box in itself (orthographic projection matrix projects to a side of the box). After the box is rotated (for different light direction), the AABB can still be computed easily (but it will be a little bigger than originally, so it is a bit wasteful).
I compute it like this: Rotate every corner of the bounding box, then find the new min and max corner from the bunch of new coordinates. An AABB is essentially just a pair of min and max points.

You can check AABB-AABB intersections after that which should be quite fast.

  • \$\begingroup\$ How do you build your shadow camera? Do you build a frustrum from the main camera and use the min/max X/Y/Z and use that as input for an orthogonal matrix? \$\endgroup\$ Commented May 12, 2015 at 14:20
  • \$\begingroup\$ No, I have 3 shadow cameras with different sizes for different cascades, such as close, mid and far cascades. Each set up by hand with different size and distance from main camera, but with same resolution. The shadow cameras are placed on the ray shot from the main camera (the camera's lookAt vector). I build a shadow camera box when creating its projection matrix. \$\endgroup\$ Commented May 12, 2015 at 22:52
  • \$\begingroup\$ "The shadow cameras are placed on the ray shot from the main camera (the camera's lookAt vector)" - can you explain this more? Isnt it like... get the center of cascades frustrum and offset it in the light direction? The question is... offset by how much? \$\endgroup\$ Commented May 13, 2015 at 14:17
  • \$\begingroup\$ I mean that I offset each shadow camera in front of the main camera (where it's facing) by a value. The bigger the shadow camera box, the further. So when each frustum is placed, I rotate them by the light direction around their own center. \$\endgroup\$ Commented May 13, 2015 at 15:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .