Skip to main content
gamedev.net
🔒 Locked

Controlling Shadow Mapping

Started by ZaiPpA 6 replies 1.8k views
Original Post
ZaiPpA
ZaiPpA
Hi! [smile] I have a small question about (basic) shadow-mapping. This is not about the aliasing or the numerical imprecision, but more about how to "control" the shadow-map in a scene, so that the scene is correctly shadowed no matter where the eye-camera is placed or where it is looking at. (Words i use: "light-camera" = the virtual camera placed at the lightsource, "eye-camera" = the normal camera) The problem: (which leads to my question) The light-camera should be able to see at least the part of the scene that the eye-camera can see. (the entire eye-camera frustum should be within the light-camera frustum) Otherwise the parts of the scene that the eye-camera can see, but the light-camera can't see, won't be shadowed. One could move the light-camera (change the position and orientation) when the eye-camera is moved, but that will change the direction of the shadows. (and could possible miss shadows from some occluders, if the light-camera is being moved past some of those) One could of course place the light-camera such that the entire scene is visible from it - i.e. place it far away from the scene. But when using point light-sources, this will (as mentioned) change the direction of the shadows. (shadows fall differently when the light-source is far away, than when it is close) Also, it will cause great aliasing to place the light-camera this far away from the objects in the scene. (at least if the scene is sufficiently large compared to the resolution of the depth-texture) (well, at least these are problems when doing point light-sources, due to the perspective projection in pass 1. For directional light-sources, i guess it might work, because of the orthographic projection in pass 1. (as no matter how far away the objects are from the light-source, they won't change size seen from the light-cameras point of view).) My question: How is this normally handled, when applying shadow mapping to a scene? (how are those problems normally avoided / worked around?) In other words, how is shadow mapping normally used, such that you can control your lightsources and at the same time ensure shadowing of the entire visible scene? Thanx! [smile] (i only know basic shadow mapping with no fancy stuff, so please try to restrict yourself to discussing basic shadow-mapping)
Matt Aufderheide
Matt Aufderheide
You are talking about some very important and fundamental things for which there are no definite "right" answers. Also it depends on what kind of scene you have.

I assume you are talking about for the moment a single directional light, like the sun.

The basic method does indeed involve moving the shadow projector position. Because its a directional light, it should be using an orthographic projection matrix (or some modified version). This means that as long as the view or rotation matrix for the sun shadow camera is kept the same, the position will not alter the direction of the shadows.

In your scene (lets assume its a big field) you will have have some normalized direction vector that will be the sunlight direction. You then need to determine a "virtual sun position" that will be the world coords for the sun shadow cam/projector.

--------------------------

In my own engine, I do it this way: every frame or so take the view position, and cast a ray out from the view pos using the reverse sun direction vector to a certain length...essentially you are making the suncam actually face the view position at all times by using the direction of the sunlight.

IF this seems hard to visualize, think of the sun camera actually orbiting around the view position, so it always looks at the view position, and also faces the exact same direction as the sunlight.

What this does is give you a position that will always cover an area around the viewer.

--------------------------

What you do then depends on what kind of shadow mapping scheme you want. A very basic, naive implemention would then use a wide a projection matrix and as far a distance from the viewer position as possible, and render a huge area into the shadow buffer. This will give a very low res shadow map, but it will always move with the viewer wherever it is.

Of course this a not a good enough implementation as I'm sure you know...but then you can do things like split frustum shadows or logarithmic distortion, etc. All of those will manipulate the projection matrix for the shadows to somehow coincide better with the viewers projection matrix.

Ultimately, you want to make sure you get all blockers that can affect the scene (within certain limits).

For instance, you could map the shadow projection matrix to match the corners of the viewers view projection matrix transformed back to world space. Then you can cull the objects not in this new frustum.

I hope this helps a little...I'm interested in other suggestions also.
Eternal
Eternal
Quote:
Original post by ZaiPpA
The problem: (which leads to my question)

The light-camera should be able to see at least the part of the scene that the eye-camera can see. (the entire eye-camera frustum should be within the light-camera frustum)
Otherwise the parts of the scene that the eye-camera can see, but the light-camera can't see, won't be shadowed.

In general this is not a problem, but correct behaviour. The frustum of your light-camera represents the volume which can be lit by the light. Anything this camera can't see isn't lit and so doesn't need shadowing either, because it already is "in shadow".

For sunlight, conceptually, it's more of a problem of shrinking the suns theoretical frustum down to what's really needed, not making it cover the view-frustum.
MJP
MJP
There's a sample on the XNA CC website that shows you how to create orthographic projection for a directional light that fits the view frustum. Even if you're not using XNA or C# you should be able to get the basic idea of how to do it from the code.

From there, you'll want to look into techniques that optimize shadowmap resolution like Matt was talking about. The most common (and IMO, most effective on its own) technique these days is Cascaded Shadow Maps (CSM), otherwise known as Parallel-Split Shadow Maps (PSSM).
ZaiPpA
ZaiPpA
Thanx for the replies everybody! [smile]

Matt Aufderheide, it's a very nice solution for directional light sources. Thank you very much for your good description! I will have to look into CSM/PSSM at some point. I'll also take a look at the XNA samples.

Ok, so we can conclude that it is not too hard to control shadow mapping for directional lightsources.

How about point lightsources?
Who do people handle those?

(They seem a lot harder, since their position (instead of direction) also affects the shape of the shadows, so you can't just move those around - at least not naively)



Quote:
In general this is not a problem, but correct behaviour.
Hehe, yeah, you're completely right that if your light source is a 'square spotlight', there are no problems at all. :) Good point.

(of course, my question is more about how people use shadow mapping for point and directional lights. The shadow mapping technique implicitly assumes that the light source is a 'square spotlight' (or some kind of weird 'square directional light', if using orthographic projection), but it is probably usually used for point or directional lights.)
Quote:
For sunlight, conceptually, it's more of a problem of shrinking the suns theoretical frustum down to what's really needed, not making it cover the view-frustum.
I'm not entirely sure that i understand what you mean. Do you mean that if, for example, the entire view-frustum isn't visible (e.g. if a big wall is right in front of you), then there is no point in covering the whole view-frustum? Or is it related to the optimization techniques?
Wyrframe
Wyrframe
Quote:
Original post by ZaiPpAHow about point lightsources? [How] do people handle those?

I suppose a cubemap would do, if one must have 360° light emanation. Often, however, point lights are restricted to spotlights of at most a 90° frustrum, more often only 30° (a typical frustrum angle for a flashlight).
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
Eternal
Eternal
Quote:
Original post by ZaiPpA
Quote:
For sunlight, conceptually, it's more of a problem of shrinking the suns theoretical frustum down to what's really needed, not making it cover the view-frustum.
I'm not entirely sure that i understand what you mean. Do you mean that if, for example, the entire view-frustum isn't visible (e.g. if a big wall is right in front of you), then there is no point in covering the whole view-frustum? Or is it related to the optimization techniques?


In your opening post you said "The light-camera should be able to see at least the part of the scene that the eye-camera can see.", but as I said this is not necessary. However, in the case of the sun, the light-frustum would be really huge and indeed cover the whole eye-frustum. It would just also cover a lot of shadow-receivers that the viewer can't see and a lot of shadow-casters that can't cast shadows into the eye-frustum. So you are really trying to find the smallest frustum that covers all potential receivers (need to be inside both view-frustum and light-frustum) and casters (need to be inside light-frustum and between the light and any receiver.)

And for point lights, yeah, use cubemaps. (or maybe dual-parabloid maps, but I think starting with cubemaps is easier.)
ZaiPpA
ZaiPpA
Thanx for the replies. Sorry for long unexcusable delay.
Quote:
Original post by Wyrframe
Quote:
Original post by ZaiPpA
How about point lightsources? [How] do people handle those?
I suppose a cubemap would do, if one must have 360° light emanation. Often, however, point lights are restricted to spotlights of at most a 90° frustrum, more often only 30° (a typical frustrum angle for a flashlight).
Ok, so if place 6 cameras at 90° angles to one another, and render into the 6 cube faces it would work. (i read a nice trick on this very forum: just render only one of the faces each frame, to sacrifice time cohesion for rendeing speed, so that it isn't any slower than regular shadow mapping)

Ok, so like if for example the lightsource is a lamp, the lamp-shade will shadow most of the light, so maybe just 60° are needed. (i haven't really seen any new games with shadow mapping, so i don't know how point lights are mostly used)
Quote:
Original post by Eternal...So you are really trying to find the smallest frustum that covers all potential receivers...
Ok, i get what you're saying. Any pointers (links or stuff) to methods for how to make this minimal frustum?




I think i got the answers i was looking for. Thanx for the replies all.
If anyone has any cool methods/tricks they would like to add, on how to "control" shadow mapping, please don't hold yourself back. It is probably interesting to other people than just me.

Btw, is there a proper/accepted term which people use, instead of my lame "control" term?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.