Sign in to follow this  
B_old

Reduce shadow swimming for rotating camera

Recommended Posts

Hello, in this forum I found a good method to reduce shadow swimming in situations where the camera gets translated. You adjust the translation of the shadow transformation so that it "snaps" to the texels and could be implemented like this:
	//Reduce shadow swimming caused by camera translation
	const float halfShadowRes = float(m_shadowRes) * 0.5f;

	Vector2 texCoords(viewProj.m30 * halfShadowRes, viewProj.m31 * halfShadowRes);
	Vector2 d = (rounded(texCoords) - texCoords) / halfShadowRes;

	viewProj.m30 += d.x;
	viewProj.m31 += d.y;

This however will fail if I rotate the camera and I can't find a good solution for that. I'm not even sure that I understand why its still swimming during rotation. It would be cool to reduce the swimming for camera rotation as well.

Share this post


Link to post
Share on other sites
"Shadow swimming", what the heck is shadow swimming ? Do you mean lag, that when you move or rotate the camera your next rendered frames is rendered with an "old" shadowmap ?

If this is the case, you got a render order problem, that is
1. render scene (with use of shadowmap)
2. render shadowmap
which will result in choppy or maybe "swimming" shadowmaps.
In this case you have to get the rendering in the right order:
1. render shadowmap
2. render scene

--
Ashaman

Share this post


Link to post
Share on other sites
Nope, that is not my problem.
By "shadow swimming" I mean, that the edges of the shadow seem to moving when the camera is moving. I thought I had seen that term used before for the behavior I mean. Do you know what the common term for this is?

Share this post


Link to post
Share on other sites
I think I know what you mean. Perhaps this is from low sampling of your shadowmap? What technique are you using to get your map?
Otherwise, look at this:
http://www.cg.tuwien.ac.at/research/publications/2007/Scherzer-2007-PCS/Scherzer-2007-PCS-Preprint.pdf

Share this post


Link to post
Share on other sites
Shader x6 4.Shadows
4.1 Stable rendering of cascaded shadow maps by Michal Valient


Shader x7 4.1: Practical Cascaded Shadow Maps

These 2 both provide details on the stabilization methods used with shadow maps and how to achieve them. Its pretty straightforward really.

Share this post


Link to post
Share on other sites
Quote:

This however will fail if I rotate the camera and I can't find a good solution for that.

Who said you have to rotate the shadow map so that it's aligned with the camera all of the time?

Quote:
I'm not even sure that I understand why its still swimming during rotation.

It's because how you're hitting the samples changes. Let's say your shadow map is oriented so that some triangle edge is almost horizontal from its point of view, (so the render target stores a straight line with a few jags in it), and then another orientation has that same edge oriented so that it is at a 45d from the shadow's POV (so the render target stores a line with a stairstep with a slope of 1). Obviously, you have two entirely different patterns for hte line there, so sampling those two will look different.

Share this post


Link to post
Share on other sites
clamp the shadows position/direction eg to the nearest meter

eg shadowcenter = camerapos + camera_forward*100
round_to_nearest( shadowcenter.x, 1.0 );
round_to_nearest( shadowcenter.z, 1.0 );

Share this post


Link to post
Share on other sites
Thanks for the replies!

@lefthandman: This seems like more than I'm looking for...

@OrangyTang: Hm, I don't think I understand. If I made a sphere around the camera position than the shadowmap wouldn't change when I rotate the camera, but I would waste a lot of resolution for stuff I'll never see. But if I make a sphere around the current split only, it will still change when I move camera, right? I don't get it.

Quote:
Original post by AndyFirth
Shader x6 4.Shadows
4.1 Stable rendering of cascaded shadow maps by Michal Valient


Shader x7 4.1: Practical Cascaded Shadow Maps

These 2 both provide details on the stabilization methods used with shadow maps and how to achieve them. Its pretty straightforward really.

I don't suppose those techniques can be viewed online? I think the stuff I am doing for camera translation is from a forums users thread to get some help with the implementation of one technique presented in one of those books.

Quote:
Original post by Cypher19
Who said you have to rotate the shadow map so that it's aligned with the camera all of the time?

Thanks for the explanation. Its not really that I am rotating the shadowmaps, but when I rotate the camera the "look at" point for shadow rendering will also move. Isn't that normal?

Quote:
Original post by zedz
clamp the shadows position/direction eg to the nearest meter

eg shadowcenter = camerapos + camera_forward*100
round_to_nearest( shadowcenter.x, 1.0 );
round_to_nearest( shadowcenter.z, 1.0 );

Hm, maybe something like that would work. Does anyone else do this?

[Edited by - B_old on June 20, 2009 2:59:27 AM]

Share this post


Link to post
Share on other sites
Quote:
Its not really that I am rotating the shadowmaps, but when I rotate the camera the "look at" point for shadow rendering will also move. Isn't that normal?


Oh yeah, that'll happen. As long as you round the look-at point to the nearest pixel, it'll be fine, but I thought you were doing that already.

Share this post


Link to post
Share on other sites
For all I know I am doing that (code in my first post). But that only solves the problem for a translated camera.
Maybe I have misunderstood something here, but I was under the impression that there is one fix for translation and another fix for rotation of the camera. Hm.

Maybe its because the size of the current split can change slightly when I rotate the camera. I'll take another look.

EDIT: Its definitely about the boundingbox changing size. If I use a bounding box with a halfsize 0.5f * current-split-far (so its really a sphere, as suggested in the guerilla paper) it seems to be perfect. Can I safely assume that 0.5f * current-split-far will always work? I don't so any problem yet.

[Edited by - B_old on June 20, 2009 8:44:14 AM]

Share this post


Link to post
Share on other sites
I'm making a new post, because I hope for your opinions on this:

Using 0.5f * current-split-far turned out to not be the best idea. Above all this will get strange results if the fov is very wide.

So I tried this instead:

//points[0] is the lower left point on the near plane, points[7] the upper right point on the far plane
float size = 0.5f * distance(camera.getFrustum().m_points[0], camera.getFrustum().m_points[7]);

size = 0.01f * floor(100.f * size + 0.5f);

aabb.setHalfsize(Vector3(size, size, size));


This works generally good. There is no shimmering anymore and it performs good for very wide fovs as well.
However I believe the aabb is bigger than it needs to be, so that I am wasting som space on stuff that already is in the previous split.
Any idea on how to get the optimal bounding box size?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this