-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cascaded shadow maps: Fix prepass ortho depth clamping #8877
Conversation
Thanks for the quick fix! This does mean that in a directional light shadow pass we're now running the prepass fragment shader of every mesh seen by the directional light right? That seems like a high price to pay for a fix, although I don't have a better solution. |
It does, and I too don't see an easy way out of this :( That said, I wonder if the GPU side of shadow draws is more draw count / vertex bound and less fragment bound? |
@cart did you mean to push all the GPU counter commits as well? |
Haha nope (I was profiling the change). Fixed :) |
Find anything interesting in the profiles? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My profiling couldn't detect a meaningful performance difference in the directional light shadow pass from this change (many_cubes example, but fixed to a specific camera view). Its possible that with more (or different) entities (or more directional lights) this could get more pronounced, but this seems like a reasonable fix for now.
@danchia wgpu 0.17 will come with gfx-rs/wgpu#3892, will that improve anything? |
Objective
Solution
Cascaded shadow maps use a technique commonly called shadow pancaking to enhance shadow map resolution by restricting the orthographic projection used in creating the shadow maps to the frustum slice for the cascade. The implication of this restriction is that shadow casters can be closer than the near plane of the projection volume.
Prior to this PR, we address clamp the depth of the prepass vertex output to ensure that these shadow casters do not get clipped, resulting in shadow loss. However, a flaw / bug of the prior approach is that the depth that gets written to the shadow map isn't quite correct - the depth was previously derived by interpolated the clamped clip position, resulting in depths that are further than they should be. This creates artifacts that are particularly noticeable when a very 'long' object intersects the near plane close to perpendicularly.
The fix in this PR is to propagate the unclamped depth to the prepass fragment shader and use that depth value directly.
A complementary solution would be to use DEPTH_CLIP_CONTROL to request
unclipped_depth
. However due to the relatively low support of the feature on Vulkan (I believe it's ~38%), I went with this solution for now to get the broadest fix out first.Changelog