Computing bounds for orthographic proj for directional lights for shadow mapping

I’m new to shadow mapping, and got shadow mapping working with directional lights with some hardcoded values.

Here, I compute the light view matrix, making use of the AA bounding box of the scene. The mid pt of the bbox is chosen as the eye, the target is (or center) is mid_pt + direction, and up direction is always (0, 0, 1). Then I hardcorded the ortho projection to have the bounds (-100, 100, -100, 100, -100, 100). This gives reasonable results, but I want to evaluate everything programatically so that I can get the most reasonable shadows, based on the viewing frustrum, etc.

I’m trying to understand how to determine the ortho proj. programatically. I can multiply the AA box vertices of the scene by the light view matrix. That gives some sort of OBB now in light space. I’m trying to understand now how to get the bounds of the ortho projection from the OBB. How do I do this? I think you can extract, the axis in light space (the new x, y, z in light space), and try to do a projection of the length vectors of the OBB, but that sounds complicated (maybe an easier way to do this that I’m completely missing).

Would love to have an answer from someone who has done this. Also, is the up direction (0, 0, 1) always right? I guess since it’s a directional light, it doesn’t matter (I think).

[QUOTE=mccloud35;1292984]I’m trying to understand how to determine the ortho proj. programatically.
I can multiply the AA box vertices of the scene by the light view matrix.
That gives some sort of OBB now in light space. [/QUOTE]

In the light’s eye-space, yes.

I’m trying to understand now how to get the bounds of the ortho projection from the OBB.
How do I do this?
I think you can extract, the axis in light space (the new x, y, z in light space), and try to do a projection of the length vectors of the OBB, but that sounds complicated (maybe an easier way to do this that I’m completely missing).

You’re almost there. Compute the min and max X, min and max Y, and min and max Z of the OBB corner points in light’s eye-space. That’s the bounds of your light ortho projection “box”.

Also keep in mind that if you’re trying to compute the bounds of what you can see in the eye frustum, and the eye frustum is perspective, then your starting 8 points are the 8 points defining that perspective frustum (which isn’t an AABB). Transform these by the light’s viewing matrix to get them into light’s eye-space. The compute the min/max X/Y/Z to get your ortho projection box.

Also, is the up direction (0, 0, 1) always right? I guess since it’s a directional light, it doesn’t matter (I think).

It depends on your use case. I think you implied that your light rays will point “forward” along the -Z axis in light’s eye space (which makes sense). The “up” vector you provide ends up being forced to be perpendicular to this “forward” direction. So the only time you’ll have a problem is if your “up” vector and your “forward” vector are parallel. That is, if your light source is directly above along (0,0,1) (or really close to that). In that case, your viewing transform computation may fail.

So you just need to think about that case and whether it can ever even occur with your usage.

Thanks for your explanation I got it work! After trying it out and making a few mistakes, I got it to work. I have a follow up question due to a mistake I made.

I was keeping track of the bounding box with max and min 3D points of the box. Then, if I simply used this and transformed them to light space, and tried to get the bounds of these two points, it didn’t work. Simply gave the wrong results.

But, if I used the bounding box corners and then transformed them to light space, and then computed the bounds. This worked as intended and allowed me to correctly compute the ortho projection.

I’m trying to understand properly, why the first approach didn’t work.

[QUOTE=mccloud35;1292990]I have a follow up question due to a mistake I made.

I was keeping track of the bounding box with max and min 3D points of the box. Then, if I simply used this and transformed them to light space, and tried to get the bounds of these two points, it didn’t work. Simply gave the wrong results.[/QUOTE]

Right. That’s why I said to compute the bounds in “light’s eye-space”, not in some other space such as world or camera’s eye-space.

But, if I used the bounding box corners and then transformed them to light space, and then computed the bounds. This worked as intended and allowed me to correctly compute the ortho projection.

Makes sense.

I’m trying to understand properly, why the first approach didn’t work.

The light projection matrix is defined as the bounds in light eye-space (min/max X, min/max Y, min/max Z). So you have to compute an accurate bounds for your entire region in that space.

With the first approach, you’re bounding in some other space. Consider the pathological example that in that “other space”, your light rays run diagonally through the min X,Y,Z point and the max X,Y,Z point in that “other space”. Then you transform those two points to light eye-space (which involves some rotation), and low-and-behold, you find that transformed points actually have exactly the same X and Y in light’s eye-space but just have different Z values. So you conclude that the needed width and height of your light space projection frustum is 0 by 0 … which is of course nonsense. You know that the volume started as a box, so this can’t be right. So hopefully you can see that transforming those min/max points from one space doesn’t make them a reasonable min/max in another space.

Does that make sense?

I think it does make some sense, when you think of a pathological example like that. But, I learnt a ton and improved my linear algebra knowledge trying this out, and making so many mistakes. I now have follow up questions about improving my shadow resolution. But, I think that belongs to a separate thread. Thanks so much for all the help, it really helped me to learn.