Potential workaround for SceneCaptures causing VSM cache invalidation each frame

Hello,

As already mentioned in [Content removed]

Having dynamic shadows disabled on scene captures results in the VSM cache being invalidated each frame. Unfortunately, this behaviour still occurs in UE 5.6 EA.

In our project, we use `SceneCaptureComponent2D` as a mirror and cannot disable them. For performance reasons, shadows in the scene capture are only enabled on Epic Quality settings, having them enabled all the time is not a great option.

This puts us in a dilemma: either accept the performance cost of shadows or the performance hit caused by VSM cache invalidation.

After some investigation, we found a workaround that seems to consistently fix the VSM cache invalidation when our mirrors are active. In `FVirtualShadowMapArray::Initialize`, we pass a boolean flag to indicate if the current view is a SceneCapture. If so, we force the full initialisation logic to run—even when `bEnabled` is false.

modifications:

[Image Removed]

[Image Removed]

[Image Removed]

[Image Removed]

With these changes, we avoid the cache invalidation, resulting in ~2.4-2.6 ms `ShadowDepths` savings in our main render.

first trace, scene capture on, vanilla - 8.2 ms

[Image Removed]

first trace, scene capture on, with modifications - 5.8 ms

[Image Removed]

second trace, scene capture on, vanilla - 10 ms

[Image Removed]

second trace, scene capture on, with modifications - 7.4 ms

[Image Removed]

Although we have not detected any issues, I would appreciate your feedback on whether this modification could lead to any unforeseen problems.

Thanks!

Steps to Reproduce

  1. open TestMap
  2. hit play
  3. run cheats
    1. r.Shadow.Virtual.ShowStats 1
    2. r.Shadow.Virtual.Visualize cache
    3. ShowFlag.VisualizeVirtualShadowMap 1
  4. run `ce StartCapture` to active scene capture
  5. run `ce EndCapture` to disable scene capture

Hi Manuel,

Thank you for the detailed info and repro!

I’ll investigate and discuss with the team. I am fairly certain that we, at one point, did in fact fix this issue but it has clearly regressed again.

Best,

Ola

Looking at the code now, I think a simple workaround (though I appreciate this may not be what you want) is to enable Dynamic Shadows for the Capture Component. This is the main thing that is different now I think, so it seems we actually reversed the problem when we fixed the original issue.

Hi Ola,

thanks for looking into it, as mentioned above we would rather not enable dynamic shadows. Maybe a fix is found in the future, till then we will continue using the workaround. I will update this post if we ever encounter issues or find a better way.

Best,

Manuel

I’ve submitted a fix based on yours, but instead of making a special case for scene captures I check the state of UseVirtualShadowMaps for the scene inside FVirtualShadowMapArray::Initialize and use that instead of bEnabled for the conditions there:

`// Always retain the VSM cache data if the feature is enabled.
const bool bShouldRetainCacheInfo = UseVirtualShadowMaps(Scene.GetShaderPlatform(), Scene.GetFeatureLevel());

if (bShouldRetainCacheInfo)
{

if (bShouldRetainCacheInfo && bUseHzbOcclusion)
{`That should be the desired behavior regardless of what caused bInEnabled to be false for the given scene renderer. This fix will land in 5.7 so we’ll have time to monitor if any fallout crops up.

Thanks again for the report & repro!

Ola

Thank you Ola for the help

Manuel