Constant invalidation of VSM dynamic shadows in 5.7.0

Having VSM shadows invalidated every frame causes significant performance issues for projects that rely on it. This behavior is not present in 5.6.1.

Steps to Reproduce

  1. Start a new project
  2. Open a new open world map
  3. Enable the Virtual Shadow Map > Cached page view mode

Observe that everything is blue around you, even if there are no objects that should be invalidating it

Hi there.

This is the intended default behavior in 5.7. The cause of this forced dynamic invalidation is the r.Shadow.Virtual.UseReceiverMaskDirectional CVar, which now defaults to true in 5.7. If you want to revert to the behavior from 5.6.1, you can disable this CVar. However, this CVar has been enabled due to performance benefits in the most common cases. From the commit description that added this CVar:

“When enabled via r.Shadow.Virtual.UseReceiverMaskDirectional, receiver mask will be used for all dynamic pages (which will thus become uncached as it is unsafe to cache partial pages), but static pages can remain fully cached. This is generally a benefit to most applications as relatively static objects should migrate to the static pages, while dynamic pages are frequently invalidated every frame.”

This means that even though visible dynamic pages are technically invalidated every frame, it will only actually be redrawing geometry that has recently moved. To get a better idea of what is actually rendering in the shadow map, you can take a look at the shadow casters view mode. With r.Shadow.Virtual.UseReceiverMaskDirectional enabled, anything that is blue (dark or light blue) or magenta will be rendering in the shadow map that frame. You can grab moveable objects, and move them around in this viewmode and see them switch back to static, not invalidating, after releasing them and waiting a short amount of time. You can also check how many nanite clusters and non-nanite mesh instances are actually getting drawn by turning on the virtual shadow maps statistics display. Note that in the example repro (with no moving objects), nothing is actually being drawn in the VSM, despite all dynamic pages being uncached.

Since, this is expected behavior, I will be closing this case off, but feel free to respond and re-open the case if you have anymore questions or concerns about this.

Regards,

Lance Chaney

hmm. if i move a mesh like you mentioned, the area goes red. but if you put a mesh with a world position offset shader there, it doesn’t change colors, so it’s not telling the truth to us about which pages are being invalidated or not.

it used to work properly in the prior UE…. is there a new way we’re supposed to find out which pages are truly being invalidated?