# OpenGL Shadow Mapping a Directional Light

## Recommended Posts

There seems to be plenty of articles about the shadow-mapping technique, and how to set OpenGL up to do it, but I find it exceptionally hard to find any material on how to create the light-source matrices. Here is an example of what I mean, from an online tutorial:
Pseudo-code in Pass 1:
PushState(ViewPort);
PushState(ViewMatrix);
PushState(ProjectionMatrix);
DrawScene();
PopState(RS_ProjectionMatrix);
PopState(RS_ViewMatrix);
PopState(RS_ViewPort);
The only thing holding me back right now is the creation of the shadowLightViewMatrix and shadowLightProjectionMatrix matrices, especially for directional lights. If I have a spotlight, it should be enough to match the cone of the light in my perspective matrix. I guess. But a directional light has no position. I must somehow position it to encapsulate the range of my main-camera frustum. I have never seen a tutorial explaining how to do this. Additionally, with either method, I need to select near/far planes that only barely encapsulate the geometry visible to them. And it needs to be orthogonal. How wide/tall do I make it? Can anyone explain how to derive these matrices? Thank you, L. Spiro

##### Share on other sites
The projection matrix for a directional light is just an orthographic projection - there isn't any need for perspective. To create it, you need to determine what the frustum size must be to fit your relevant geometry in it.

The view matrix can just be chosen to be from a position that allows your chosen frustum to encompass all of the needed geometry. Creation of the matrices is usually done by the D3DX library for me, but any standard graphics text should show the derivation of the matrices if you need that level of detail.

##### Share on other sites
In OpenGL there is a function glOrtho for creating orthographic projection matrix. As Jason Z wrote you can use any position for the light that is far enough to "see" all geometry that you want, because created shadows don't depend on the position in that case. The same goes for clipping planes. So everything is up to you :)

##### Share on other sites
I guess I was hoping for a sample of that math that appears in some texts, because it appears in none of the texts I have read. I left my books at work, but among them is Advanced Graphics Programming Using OpenGL (The Morgan Kaufmann Series in Computer Graphics), which again covers the concepts (which I understand clearly) but not the math.

I have a view frustum that is basically a pyramid with its top chopped off.
Then I have a box (representation of an orthogonal frustum projected from the directional light) at an arbitrary angle that needs to enclose that.
So I am guessing I need to take the dot product of the up/right vectors with the points that mark the corners of my view frustum to find the extremes in all directions, then take the objects that fit in that box and use a similar method to find the extreme far/near AABB’s of those objects.

Except there are no points in my view frustum; it is set up as 6 planes.
Calculating the intersection points of all the planes, while possible (and I know how to do it) seems slow, and I am sure there is a more efficient method.

As my engine is cross-platform (from iPhone to Nintendo Wii to Xbox 360), I will not be using any API-specific functions from OpenGL or DirectX.
I need the raw math behind this, or a pointer to a paper that has this mythical and mysterious math.
In the meantime I will of course continue searching for this, since you say it exists somewhere.

Thank you.
L. Spiro

##### Share on other sites
Hi!

like dys129 said, a common method go get the matrices in OpenGL is just to set the glOrtho and make a glGetMatrix(), but that's not really necessary. It is possible to set the matrices together by yourself, because a glOrtho() just multiplies an orthographic Matrix with the current Matrix (which is normally a Identity Matrix).

I don't know if you have seen that, but here you can see how OpenGL builds the orthographic Matrix:

http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml

As said before, the values depend on you scene. For example I take:

glOrtho(-40,40,-40,40, 0.1f,500.0f);

I guess to calculate the best fit of your view frustum, it would be good to have the bounding spheres of the objects. Then you set the orthographic near plane on the nearest bounding sphere - radius (of it) and the farplane on the farthest bounding sphere + radius (of it).

##### Share on other sites
Thank you all for your replies.

The numbers I am interested in finding are the numbers that you would plug into glOrtho(). I know how to build the matrices; I do not know what numbers I am supposed to feed them.

glOrtho(-40,40,-40,40, 0.1f,500.0f);

How did you come upon 40?
Does it always encompass your full scene from your view frustum’s point of view?
I have a feeling that if it does then you have a special situation in your game.

I know that one option is to make one orthogonal projection that fits the whole world and just use that all the time. It also prevents shadow flicker when the camera moves.
But it is also the worst possible way to go; you have terrible depth precision and do not make full use of the limited texture space you have, which results in terribly low-resolution shadows.

So I want to snap the orthogonal projection to essentially be an AABB of the view frustum, and this is the math I need.
I proposed my idea for how to do this above, by taking extreme points of the view frustum in the up/right directions of the light vector, but I felt that this might not be the most efficient way (although it will work).
This is where I would get the width/height to feed into glOrtho() (or rather my own matrix functions).

It seems that everyone is suggesting I use the actual objects inside my main view frustum to derive the width/height of the orthogonal projection from the light. But I would run into the same math problem regarding how to size my orthogonal projection to fit them (although it does become simpler if I use their bounding spheres rather than their AABB’s, and if that is the way I go I would not need help with that math), however this method causes shadows to disappear when the object casting them is no longer in view. For example a tall building no longer casting a shadow on the street just because the player looks down.

But that method has the advantage of not needlessly stretching the orthogonal projection out into the distance of there are no objects out there, which increases the quality of the shadows.

I will size the orthogonal projection to fit my main view frustum (which I still need the math to do), then cull objects from that box, with the far plane being derived from the fitted box and the near plane being set back to the edge of my world box.
Then among those objects I will tighten the orthogonal projection using the bounding spheres of those objects (for which I do not need the math).

I wonder if this will be too computationally expensive.

I guess all I need is the method/math for fitting an orthogonal projection around a view frustum.

L. Spiro

##### Share on other sites
If I am in the wrong here, please forgive me, but I think I had a similar problem earlier.

These are a few steps to finding a good ortho frustum around your scene. Remember, that just because it is in the view frustum, there still exist objects outside the view frustum potentially that cast shadows into the view frustum (so you have to extend the box to include those).

This is how to calculate the minimum orthographic frustum around a arbitrary view frustum (as long as you can calculate it's eight corners).

1. Calculate the camera corners for your perspective transform in world space (To do this, calculate it in view space using trigonometry and then use the inverse view matrix to get the objects from view space to world space):

2. Rotate the vertices so that they are in the direction of the sun. To do this, I simply multiply every single corner by this matrix: gluLookAt (0, 0, 0, sx, sy, sz, 0, 1, 0) .

3. Now that you have the rotated vertices, it is a simple matter of finding the AABB around them, because you are in the light's view space. So find the maximum x, y, and z, values, and also the min x, y, and z values.

From here, you have the box, and creating an orthographic persepctive is trivial. The position of the camera will be at lightRotationInverse * (cx, cy, mz), where lightRotationInverse is the inverse of the matrix created in step 2, and (cx, cy, cz) is the center of the frustum in the light's view space, and mz is the minimum z value for the frustum's box.

There was a great XNA sample code that I used to determine how I should do this, but alas, I cannot find it. Search google for terms and add XNA maybe? I don't have the time to search.

Good luck!

##### Share on other sites
Thank you; this is essentially what I wanted.

In my original explanation of my idea I thought that calculating the 8 corners of the view frustum would be pretty expensive so I thought there must be another way to do it to get the orthogonal dimensions directly from the 6 planes (of the view frustum).
But I guess not. Seems I will have to get the actual corner points anyway.

In that case I can proceed, but I think (I could be wrong) that it would be faster to use the dot products of the up/right vectors of the directional light against all 8 points (as opposed to transforming them via the inverse view matrix of the light). Both methods require a loop over the vertices and a min/max comparison, but the dot product is cheaper than a matrix multiply with a vector.

I think this is what you found before:

If I am right, maybe you can even speed up your own implementation!
Just let me implement my idea first to see if it even works.

L. Spiro

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
627697
• Total Posts
2978680
• ### Similar Content

• Both functions are available since 3.0, and I'm currently using glMapBuffer(), which works fine.
But, I was wondering if anyone has experienced advantage in using glMapBufferRange(), which allows to specify the range of the mapped buffer. Could this be only a safety measure or does it improve performance?
Note: I'm not asking about glBufferSubData()/glBufferData. Those two are irrelevant in this case.
• By xhcao
Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness.
• By cebugdev
hi guys,
are there any books, link online or any other resources that discusses on how to build special effects such as magic, lightning, etc. in OpenGL? i mean, yeah most of them are using particles but im looking for resources specifically on how to manipulate the particles to look like an effect that can be use for games,. i did fire particle before, and I want to learn how to do the other 'magic' as well.
Like are there one book or link(cant find in google) that atleast featured how to make different particle effects in OpenGL (or DirectX)? If there is no one stop shop for it, maybe ill just look for some tips on how to make a particle engine that is flexible enough to enable me to design different effects/magic
let me know if you guys have recommendations.
• By dud3
How do we rotate the camera around x axis 360 degrees, without having the strange effect as in my video below?
Mine behaves exactly the same way spherical coordinates would, I'm using euler angles.
Tried googling, but couldn't find a proper answer, guessing I don't know what exactly to google for, googled 'rotate 360 around x axis', got no proper answers.

References:
Code: https://pastebin.com/Hcshj3FQ
The video shows the difference between blender and my rotation:

• By Defend
I've had a Google around for this but haven't yet found some solid advice. There is a lot of "it depends", but I'm not sure on what.
My question is what's a good rule of thumb to follow when it comes to creating/using VBOs & VAOs? As in, when should I use multiple or when should I not? My understanding so far is that if I need a new VBO, then I need a new VAO. So when it comes to rendering multiple objects I can either:
* make lots of VAO/VBO pairs and flip through them to render different objects, or
* make one big VBO and jump around its memory to render different objects.
I also understand that if I need to render objects with different vertex attributes, then a new VAO is necessary in this case.
If that "it depends" really is quite variable, what's best for a beginner with OpenGL, assuming that better approaches can be learnt later with better understanding?

• 20
• 14
• 12
• 10
• 12