-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
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
Add an option to update shadow maps less often #55000
Conversation
This can be used to improve performance on low-end setups, at the cost of shadows visibly lagging behind for dynamic lights/objects when up close. Co-authored-by: Manuele Finocchiaro <m4nu3lf@gmail.com>
c36fe39
to
3b50dbc
Compare
This is a known technique, but it probably needs a bit more customization. For directional lights, what you often do is update last cascade every 4 frames and the previous to last one every 2. For point and directional lights, we already divide those in 4 quadrants. We should set the update frequency for each quadrant, with the tiny ones having less and the bigger ones having more. |
Additionally, with positional lights, if a quadrant updates every 4 frames, we should not update all together at the 4 frame intervals but staircase them so frame timing remains smooth. Doing this properly is a bit of a challenge. |
Here's my 2 cents on this matter: I Wouldn't try to mix General and Directional Shadow Updates, It'd be needlessly complex, with far too few gains, so I'd do them Separately, especially considering that Directional Shadow Processing is often Much more demanding compared to General Shadows from my experience. Directional Lights Update Modes
General Lights Update Modes
Default settings I'd use (this includes Option 0, aka current behavior): I don't see too much improvement in Performance from General Lights being staggered, especially as they can be occlusion culled, while Directional Lights would be a Significant savings in terms of performance for 4 splits, as you'd only do 2 passes instead of 4 per frame, and it'd often be preferable to have 4 splits worth of quality with a little lag for 2 splits worth of speed to having to actually use 2 splits for performance, keep in mind that Occlusion Culling doesn't affect Directional Shadow Casters because the Directional Light is always rendered, while General Lights themselves can be culled, and thus Reducing Computation in general for Directional Shadows is far more important. |
To add to this, it will need to be slightly more complex as lights move between quadrants depending on their priority. By default the closest light takes up quadrant 1 and the next few lights fill quadrant two. So the risk in not updating every frame is not that the shadows will be slightly out of date, but that a light will render the shadows from a different light. |
Honestly, I doubt General shadows in general would have any significant benefits, especially considering that afaik only shadows where something changed need to be re-rendered, and even if that were not the case, they don't have Nearly the same degree of processing required as only meshes within their AABBs get processed, and as they tend to be fairly small, they're small fish compared to Directional Shadows. I'd personally split the two into separate PRs and focus on Directional Shadows as they're easier to do, and would offer the most significant benefits which are guaranteed to be sizable in complex scenes, not to mention fairly safe from nasty bugs popping up (as opposed to General Shadows due to their complexity), and make a simple General Shadow PR that'd wouldn't take these things into consideration too much, but would be used to see to see how much of a difference it'd actually make performance wise in test scenes, to see if it's worth even dealing with the logic. Also one more consideration, Shadows that Lag could produce self shadowing on moving objects, which would be much more visible for general lights due to their much higher relative resolutions, while Directional Lights tend to be more forgiving in this regard. |
+1 to focusing on directional lights first |
Hmm, One thing I don't think was solved here, If shadows update less often, and an object is moving, the object could get a ton of self-shadowing artifacts, because essentially it, and it's effective shadow mesh, are at two very different positions. This could be solved by applying the shadows at a "staggered" rate as well, so having the shadows apply to Meshes according to where they were when the shadow was rendered and not by where they are now, but to do so, you'd need to keep past several transforms for each shadow casting object. |
Or maybe we could have static vs dynamic objects like other engines do ;) |
I think that'd be an over-complicated solution to this problem and doesn't address the root of the problem. |
This is indeed something you can see in the |
Actually, it fundamentally does, and it's really, really easy to do. There are a ton of times where this effect will be observable in practice, as any time you have something moving to it's shadows even a little, this will happen. |
|
master
version of #54516.This can be used to improve performance on low-end setups, at the cost of shadows visibly lagging behind for dynamic lights/objects when up close.
Unlike the
3.x
implementation, this one appears to work better with the default shadow bias settings when point lights are involved.Testing project: test_animated_shadows_master.zip