TSR ghosting against a VolumetricCloud the player stands inside — every rejection knob measured, none help

UE 5.8, Windows, DX12, TSR.

I have a sandstorm built as a VolumetricCloud layer on a small planet (radius 250 km). The layer floor sits 10 m above the sand, so the player walks inside the cloud during a storm — it is a haboob, the wall has to touch the ground.

Symptom. Anything that moves leaves a trail: the character, the vehicle, and also the whole scene when only the camera rotates. The trail is visible only against the lit dust, never against dark terrain, and only while the player is inside the storm’s dust. Outside the storm, even against a bright sky, there is no trail.

What I measured (each test from a freshly launched editor, one change at a time):

test result
r.SSR.Quality 0 no change
r.AntiAliasingMethod 0 trails gone (unusable — aliasing + black flicker around the character)
r.TSR.Velocity.HoleFill 0 no change
r.TSR.ShadingRejection.SampleCount 4 no change
r.TSR.History.ScreenPercentage 200 no change (already 200 from Scalability)
r.VolumetricFog.HistoryWeight 0.5 no change
r.VolumetricFog.TemporalReprojection 0 no change
r.VolumetricRenderTarget 1 (+ ini Mode=2) trails gone, but heavy square blocks of dust
r.VolumetricRenderTarget 1 + Mode 0 worse
r.VolumetricRenderTarget 1 + Mode 3 trails stay, concentric banding stays, GPU 15.2 ms
r.VolumetricRenderTarget 0 (current) no blocks, but trails + concentric banding
Standalone Game instead of PIE trails are there too

r.TSR.Visualize 0 shows the dust area uniformly green with no red at all — TSR accepts the history there and rejects essentially nothing.

Ghosting against the lit dust:

I also tried removing the cloud’s near-field “haze” term from my own material (a separate additive component, independent of the wall): no change. So it is the dense wall itself, right in front of the camera.

My reading. A VolumetricCloud writes neither depth nor velocity, so TSR has nothing to reject history on, and with r.VolumetricRenderTarget=0 the layer goes through TSR instead of being composited after it. With =1 it is composited after TSR (trails gone) but the reduced-resolution buffer shows as square blocks, because the player is inside the volume and dense matter sits in the near field — which is exactly where that reduction stops being invisible.

Questions:

  1. Is there a supported way to make TSR reject history over a VolumetricCloud (anything that gives it depth or velocity for the cloud)?
  2. With r.VolumetricRenderTarget=1, is there a way to stop the reduced-resolution blocks when the camera is inside the cloud layer, other than full-resolution tracing?
  3. Separately: the concentric banding centred on the camera gets denser when I raise View Sample Count Scale (0.55 → 1.2), so it is the ray-march step boundaries. Is there a jitter/dither for the cloud march that works with r.VolumetricRenderTarget=0?

Any pointer appreciated — including “a cloud is not the right tool for a volume the player stands in”, if that is the answer.

Your matrix already rules out the rejection knobs. Trails vanish with r.AntiAliasingMethod 0, they only show against the lit dust, and HoleFill plus shading-rejection sample count do nothing. TSR is reprojecting history against a background that has no usable velocity. SSR was never on that path.

A Volumetric Cloud drawn into the separate volumetric render target is upsampled on its own buffer. That buffer does not carry the same per-pixel velocity as the main view, and standing inside the layer means every frame’s dust luminance is a different density sample. TSR then treats that bright, zero-velocity cloud as stable history and smears anything that moved across it. Dark terrain still rejects, which is why the trail disappears the moment the background is the ground. More shading-rejection samples will not fix a signal that has no motion vectors.

Two checks, one change at a time from a fresh editor:

  • Set r.VolumetricRenderTarget 0 so the cloud is composited in the main view instead of the low-res temporal target. If the trails drop, the separate target was the mismatch. If you need that target for cost, turn off its own temporal accumulation rather than pushing TSR harder. The cloud pass is building a second history that TSR then accumulates again.
  • Confirm the character and the vehicle actually write velocity, including World Position Offset. A mesh with no velocity write trails on any background; inside the storm it is just the only place you can see it. r.AntiAliasingMethod 0 killing the trail fits both this and the cloud target, so it is worth splitting the two tests.

I would not keep tuning r.TSR.ShadingRejection or HoleFill. You already showed those do not move it.