# Reduce shadow swimming for rotating camera

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

## 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

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 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)
which will result in choppy or maybe "swimming" shadowmaps.
In this case you have to get the rendering in the right order:
2. render scene

--
Ashaman

##### 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 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 on other sites
This presentation from Guerrilla has a few details on how they stop swimming in Killzone (page 37). I think I saw a more detailed description somewhere but I can't find it right now...

##### Share on other sites

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

##### 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 on other sites
clamp the shadows position/direction eg to the nearest meter

eg shadowcenter = camerapos + camera_forward*100

##### 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:

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 Cypher19Who 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 zedzclamp the shadows position/direction eg to the nearest metereg shadowcenter = camerapos + camera_forward*100round_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 on other sites
Its called aliasing, if its shadowmaps.

You can reduce it a little bit with filters, try a blur filter.

##### 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 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 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.

//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 on other sites

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

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628730
• Total Posts
2984431

• 25
• 11
• 10
• 16
• 14