Directional light position in shadow mapping

Started by
4 comments, last by L. Spiro 9 years, 1 month ago

I've got a basic cascaded shadow mapping working, but there's alot to improve. Something thats nagging me is this:

Technically, the light must have a position when rendering the shadow maps. But, it is not supposed to have one. So how do you determine what position to use when rendering depth for each of the cascade frustrums?

The way I imagine it (and do currently) is to simply offset it some amount of distance from the cameras position. It must be trickier though because this does not take geometry into account. Do you simply sum up all the geometry in each cascade to get the max height, and then offset from that? If so, how much?

Generally the resources I've found on the net simply offsets it abit from the camera, but it must be more complex than that. Any pointers on how to do this?

EDIT: another, not too unrelated question is this: how do you do culling for directional lights? do you view frustrum culling for each cascade, each frame?

Advertisement

Technically, the light must have a position when rendering the shadow maps.

No it doesn’t. You only need a projection matrix (orthogonal in this case).

So how do you determine what position to use when rendering depth for each of the cascade frustrums?

how do you do culling for directional lights? do you view frustrum culling for each cascade, each frame?

You don’t calculate a position, you calculate an orthogonal matrix. I will answer both questions at the same time.
  • Get the camera view frustum (6 planes).
  • For each cascade.
    • Determine where you split the camera frustum.
    • Create a frustum (usually not 6 planes) based on this information.
      • The first 3 planes are the camera frustum planes that face away from the light. This creates the set of far planes (there is no single far plane).
      • The next few planes shoot in the direction of the sun and create an outline around the camera frustum where, on the camera frustum, one plane faces away from the light and the border plane faces towards the light.
      • There is no near plane unless you have a tool chain that allows artists to set one.
  • Frustum-cull. Gather objects inside the new frustum. These are objects that might cast shadows into the player’s view for the given cascade.
  • Build an orthogonal matrix based on the list of objects you just created.
    • Typically all entities in your scene will have a forward, right, and up vector, and this applies to lights as well.
    • Determine the left, right, top, bottom, near, and far values by going over each object and based off the light’s up, right, and forward vectors determine the max extents in each direction (and inverse direction). For example, to determine just the top and bottom values, given your light’s up vector and the list of objects inside its frustum:
      float fTop = -INFINITY;
      float fBottom = INFINITY;
      Vec4 vDown = -lLight.Up();
      for ( size_t I = 0; I < vObjects.size(); ++I ) {
      	float fTopDist = DOT( lLight.Up(), vObjects[I].Pos() );
      	fTopDist += fTopDist > 0.0f ? vObjects[I].BoundingSphere().Radius() : -vObjects[I].BoundingSphere().Radius();
      	float fBottomDist = DOT( vDown, vObjects[I].Pos() );
      	fBottomDist += fBottomDist > 0.0f ? vObjects[I].BoundingSphere().Radius() : -vObjects[I].BoundingSphere().Radius();
      	fTop = Max( fTop, fTopDist );
      	fBottom = Min( fBottom, fBottomDist );
      }
    • The same loop can do the left, right, near, and far as well.
You now have the top, bottom, left, right, near, and far parameters for creating an orthogonal projection matrix.
Culling objects and determining the bounding box for the cascade are part of the same process and there is no need for a light position.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Technically, the light must have a position when rendering the shadow maps.

No it doesn’t. You only need a projection matrix (orthogonal in this case).

So how do you determine what position to use when rendering depth for each of the cascade frustrums?

how do you do culling for directional lights? do you view frustrum culling for each cascade, each frame?

  • .....
  • For each cascade.
    • Determine where you split the camera frustum.
    • Create a frustum (usually not 6 planes) based on this information.
      • The first 3 planes are the camera frustum planes that face away from the light. This creates the set of far planes (there is no single far plane).
      • The next few planes shoot in the direction of the sun and create an outline around the camera frustum where, on the camera frustum, one plane faces away from the light and the border plane faces towards the light.
      • There is no near plane unless you have a tool chain that allows artists to set one.

L. Spiro

I'm having a little trouble visualizing this step. I keep thinking of a conventional view frustrum with a near, far, top, bottom, left, right plane. Do you have any references or images?

Do you have any references or images?

http://lspiroengine.com/?p=153
http://lspiroengine.com/?p=187


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

What should face culling be set to - back or front faces? I find if a object is caught between two cascades and for example back-face culling is on, it won't cast any shadows.

EDIT: also, on orthographic projection matrices... are the near/far parameters supposed to be positive? I find if I pass -0.1f as zNear and -7.0f as zFar, it seems to catch objects in the 0.1 - 7.0 range instead.

EDIT2: Also, I'm not sure why the position isn't needed. If no light view matrix, the orthographic matrix has to be atleast rotated somehow? By the light direction?

What should face culling be set to - back or front faces?

Shadow-mapping should always use back faces.

I find if a object is caught between two cascades and for example back-face culling is on, it won't cast any shadows.

It shouldn’t matter which face is culled in this case. You have a strange bug. Of course I can’t help with that right now, but if you make another topic with more information on it…

also, on orthographic projection matrices... are the near/far parameters supposed to be positive?

Typically. But you can hard-code the near plane in this case. Conceptually you are just putting the camera right behind all the objects that were culled into it. After transformation, there is no reason for an object to be “behind” the camera.

EDIT2: Also, I'm not sure why the position isn't needed. If no light view matrix, the orthographic matrix has to be atleast rotated somehow? By the light direction?

It will be rotated when you multiply it by the (light’s) view matrix. I already said that every light has a forward, up, and right vector. These go into making the light’s view matrix.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement