I see that we have csm caching but it’s very restrictive. It only seems to work if lights dont change and if objects don’t move. I wondered if it would be reasonable or feasible to have them simply cache every other frame or cache at an interval so that shadows render at 30fps despite the game being 120fps. Thanks in advance!
Hi there.
Just to clarify, the CSM caching does not cache the shadow maps for any meshes with their mobility set to movable. Currently it does not matter whether they are actually moving or not. This allows the engine to use the static mobility CSM cache, even if movable objects (that perhaps were not moving before) move. While doing what you say might be feasible, it might also require some significant work depending on what features you want. For instance, if you want to cache the shadow depths after movables have been rendered (not currently done), and perhaps scroll this cached static + movables CSM every frame to make this appear smooth, as long as nothing actually moves. Have you considered switching to, or testing Virtual Shadow Maps in your project? These have much better caching behavior for movable objects. Specifically, if an object moves, it will only update its affected shadow pages, and only when it actually moves.
[Image Removed]Affected VSM pages in blue for moving cube. When nothing is moving, everything is cached.
Regards,
Lance Chaney
Hi Lance,
We have tried VSMs but our project isn’t the right fit for Nanite so VSM’s carry a much heavier cost than usual.
Thanks for the info.
Brenden
I would recommend A/B testing VSM against CSM in your project after following the recommendations for non-nanite geometry in this documentation before eliminating the possibility of using VSMs. Particularly I would try profiling with the r.Shadow.Virtual.NonNanite.IncludeInCoarsePages CVar set to 0, as noted in the docs. I did some rough profiling on the old Northwood scene (Epic provided project available on Fab), which does NOT use Nanite meshes, and found equal or better performance with VSMs. However, this is fairly small scene, so may not be representative enough of a full game level to extrapolate performance characteristics accurately.
If your were to create something that renders shadows every other frame. Keep in mind that this would likely result in unstable framerate, which might feel even worse than lower framerate for the end user. Since every other frame could be far more expensive due to shadow rendering costs. You might be able to find some way to amortize the shadow cost over multiple frames, like rendering smaller shadow tiles, and only update a subset of tiles each frame. But this would likely result in visual artifacts. And again, you would have to do significant R&D yourself to implement something like this.
Unless you have a significant number of moving objects in your scene, I wouldn’t expect moving objects to increase shadow rendering costs significantly. Moving foliage would be the only thing that I would think would increase cost significantly. To optimize this, I would recommend turning off shadows on small foliage like grass, and turning on screen space contact shadows for this. Other than this, to reduce CSM costs generally, your biggest wins will be to reduce the CSM distance and / or the number of cascades. You will still need something to fill in the distant shadows however. You can experiment with distance field shadows, a far shadow cascade, or baked lighting for this. Good LOD chains to reduce tri-count and overdraw will also help with shadow performance. You can also try playing with r.Shadow.LODDistanceFactor, r.ShadowQuality, and r.Shadow.MaxCSMResolution to see how each of those CVars affect quality and performance.
Regards,
Lance Chaney