Archived

This topic is now archived and is closed to further replies.

Shadow Mapping, Shadow Depth Buffer, whatever you call it

This topic is 5534 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

A while back (I think it was Yann) someone answered one of my questions about how to shade terrain so that the hills actually cast shadows. He answered with a solution that I thought was brilliant, but now that I''m trying to implement it I''m having some problems. It took me a while to get around to implementing shadows into my engine and it didn''t work like I thought. The technique I''m trying to use is render the scene from the light''s perspective and do all the other stuff and take the depth buffer and apply it as a texture. I get everything except render it from the light''s point of view. Now I am shading my hills with sunlight but this technique could be used for any type of shadow casting. But in my case I have a directional light. I know how to render the scene from an orthogonal perspective. I know how to make the camera look in the direction of the light. But *where do I put the camera*? It''s directional so it doesn''t have a point either. Is this a usual problem or is there a simple thing that I am not trying? Once I get the camera positioned looking at the terrain I can do the rest, but how does the perspective work out with directional lighting? I know where the target vector is, but where should I position the viewpoint vector? Thanks for the help, James

Share this post


Link to post
Share on other sites
Yeah, I think it was me. Anyway, selecting the position for a directional light source is somewhat tricky. A directional light is basically just a direction vector, there is no explicit position (mathematically, the lightsource is infinitely far away). So you can theoretically position your directional lightview camera anywhere , as long as it points in the direction of the light vector, and the scene is infront of it (ie. visible to the camera).

That would work fine in a perfect world of infinite resolution shadow maps

First problem is the limited shadowmap resolution. Assuming you don't want to use insanely large maps (eg. 4096²) because of speed and memory, you probably won't use a single map over the entire terrain. If you do, the shadows will be blurry (although it depends on your terrain size, obviously). So, first select the part of the scene you'd like to shadowmap. That would be all parts of the terrain that are currently visible and/or could cast shadows into a visible part. If you use multiple resolution shadowmaps (shadow LODs), then take that into account here. In other words: select all parts of the scene, that are in the lightpath for the current view frustum (and current shadow LOD level, if applicable).

Now, you simpy adjust the position and orthographic scale of your camera, so that it encompasses the selected terrain parts. This is basically a 2D operation (remember, directional light has no perspective).

Next problem is depth resolution. The camera has been positioned on the plane perpendicular to the light direction, but where to position it along that vector ? Fact is, that for the results of the rendering itself, it doesn't matter. The distance is irrelevant in orthogrpahic projection, since the depth is ignored. But the problem is that your shadowmap does not have infinite dynamic range (but more something like 16 or 24bit).

Fortunately, the range can be computed easily, as you don't need very high precision. An approximation is OK: go through the bounding volumes of the selected terrain parts visible to the light (as done before to adjust the camera position), and compute the minimum and maximum extend along the light direction vector. The scene that will be rendered into the shadowmap lies between those two z values (zmin, zmax).

Now you basically have two possibilities to limit the range:

1) position the camera very far away, so that it will never interfere with any scene you have. Adjust the depth offset and scale of the projection matrix, so that zmin corresponds to 0, and zmax to 1. The GPU will clamp everything else.

or

2) Position the camera on the plane formed by the light direction vector and zmin. Adjust the depth clipping planes to match the new dynamic range (from 1 to zmax-zmin).

Now render the view of the camera into the shadowmap (or multiple maps in the case of shadow LODs).

When rendering the scene, you'll have to make sure to use exactly the same transformations as before, when projecting the shadowmap onto the geometry. That's pretty easy: keep your light camera matrix, reuse it as texture projection matrix and you'
re done.

BTW: I implemented the shadowing system we were talking about a few months ago myself, in an architectural visualization application. It looks really good, almost like raytraced realtime shadows. I have some screenies here, if someone is interested.

[Edit: typos. I'm thinking faster than I can type ]

/ Yann


[edited by - Yann L on October 21, 2002 8:31:28 PM]

Share this post


Link to post
Share on other sites
wouldn''t it be better to use vertex lighting on terrains? you could have it raytrace from a light to each point and if it hits a hill, make the vertex you are raytracing darker with the diffuse color part of the vertex FVF. if it doesn''t hit anything (the ray) on the way to the vertex, make it the color of the light + attenuation if you wanted. that way there wouldn''t be any multitexturing going on

Share this post


Link to post
Share on other sites
How do you perform shadow mapping in real-time? I know this is possible, but how do you do it in OpenGL or DirectX.

What I''m doing now is taking each pixel in the color buffer, transform it into shadow map space, and use that value to determine if the current pixel should be shaded. Of course, this is VERY slow.

Share this post


Link to post
Share on other sites
quote:

wouldn''t it be better to use vertex lighting on terrains?


It would certainly be easier and faster to implement. But the quality of the shadow mapping method is in a totally different league: well adjusted in can approach the quality of raytraced shadows in realtime.

Another big advantage of shadowmaps is their inherent ''totally realtime'' nature: you can move the sun position, morph the terrain, make objects move on the terrain, etc, and the shadowing will always be perfectly realtime without additional overhead. Also, the shadow solution is complete, means that the shadows will project from every object onto every object.

/ Yann

Share this post


Link to post
Share on other sites
I actually have implemented a vertex shading raytracing technique that you describe, but it does not have good quality. And it''s too slow for the dynamic nature I want. And it also doesn''t have the volume effect
Thanks so much Yann, I think I grasp the concept but it''ll take a few days to understand how to implement it. I''ll be working on it. It''s weird, I understand perfectly how to implement something like this for regular objects (such as a standing person) but I''m having trouble visualizing how to do this with terrain, one big self-shadowing object. I''m gonna try whatever I can and see if I can get something working anyway. Thanks again guys

And yes, we''d definitely like to see some screenshots!

Share this post


Link to post
Share on other sites
You might want to check out the following paper, and also the discussion about it on the gdalgorithms mailing list.

Perspective Shadow Maps

BTW to see how to accelerate it in hardware just check out some of the NVIDIA presentations/whitepapers.

[edited by - PinkyAndThaBrain on October 22, 2002 11:58:25 PM]

Share this post


Link to post
Share on other sites
Directional light without perspective?

once you have a direction for the light, simply rotate the mesh....then useing the the triangle X and Y values (don''t do any perspective Z stuff)...anyway use the the triangle X and Y values to cull polygons into a list...polygons that face the opposite direction cast shadows, so you want the list to contain these...you can then use the list to render shadows on the texture...either directly, or vertex shaders, or whatever....

Share this post


Link to post
Share on other sites
Hey, I got a program running with the regular shadow map technique! Yeah, it has the aliasing artifacts for now, but I was still impressed with the results. It was very cool too see my terrain self shadow real-time while the "sun" moved around.
I''m afraid some of the math provided for the "perspective" shadow maps is too complex for me to understand without any code, visual explanation or such. I read the "Perspective Shadow Map" paper and the explanations didn''t relate well enough. Maybe I''m trying to jump into something too quickly, but maybe if someone could still answer a few specific questions I can crawl my way through this.
Explain 4-d texture coordinates. How the heck does transforming oT0.x y z and w "project" the texture? I was amazed when it worked. Is there a paper out there that explains it conceptually? I don''t understand anything outside of the 2-d texture coordinates.
How am I to take the depth buffer if there is none?? I''m rendering my light from an orthogonal aspect ( it''s a directional light ), meaning -there is no depth!- Can someone explain this ?
I''m still satisfied with what I have because my first game does not have to be perfect. If I can''t get any farther than this I will just keep this for this program. Thanks again everyone.

Share this post


Link to post
Share on other sites
quote:

It was very cool too see my terrain self shadow real-time while the "sun" moved around.


Yeah, shadowmaps are cool, aren't they You won't get this with stencil shadows...

quote:

I'm afraid some of the math provided for the "perspective" shadow maps is too complex for me to understand without any code, visual explanation or such. I read the "Perspective Shadow Map" paper and the explanations didn't relate well enough. Maybe I'm trying to jump into something too quickly


The 'perspective shadow maps' paper is excellent, the technique described can be used to get rid of most of the aliasing artifacts. But it is actually not that easy to implement. A standard shadowmapper is already a very good start. Once you understood all the math behind it, then you can attempt the PSM paper.

quote:

Explain 4-d texture coordinates. How the heck does transforming oT0.x y z and w "project" the texture?


The same way as 4D coordinates project a vertex - by dividing by the homogeneous coordinate. Just think of your texcoords as regular coordinates for a vertex. But instead of projecting it onto the screen, you project it onto the scene. If you haven't already, look at this nVidia paper, it explains the concept of projective textures.

quote:

How am I to take the depth buffer if there is none?? I'm rendering my light from an orthogonal aspect ( it's a directional light ), meaning -there is no depth!- Can someone explain this ?


Orthogonal projection still has a depth value - it's just not used to perspectively distort the coordinates (as in perspective projection). But it still is there, and represents the distance of objects from your camera (or light in the case of shadow mapping) Otherwise the zbuffer wouldn't work at all. It's pretty much the same thing as with perspective rendering, ie. z is still interpolated over the surface, compared and store to the depth buffer, etc. It is just not used in the projection equation.

/ Yann

[edited by - Yann L on October 24, 2002 1:18:12 PM]

Share this post


Link to post
Share on other sites
Thanks so much Yann. You and the others here are always so willing to explain things, and then explains things some more. I think I''m going to store that Perspective Shadow Mapping paper for later and save it for my next program which hopefully will be the "next level up". I''ll probably blur the texture right now and use it as that. Thanks a lot!
As for now I will research deeper the math of what''s happening so I can really understand it, just so I know what''s going on. I understand everything (I think) except the projection part, but it''s kind of new so it''ll probably sink in. I have looked at that paper before, but it was a while ago when I thought I would never get this far. I''ll take a loot at it again. Skimming over it, it seems to have a pretty good explanation of projection. Thanks again!
James

Share this post


Link to post
Share on other sites