[UE 5.8.1][D3D12] Rough refraction destroys the scene-capture alpha channel

Summary

Rough refraction destroys the scene-capture alpha channel

Summary

With Substrate and Alpha Output enabled, a translucent material that uses the Index of Refraction refraction method writes an alpha of 1.0 (“nothing here”) into scene colour when it is rendered through a SceneCaptureComponent2D. The object disappears completely from the captured alpha, so it cannot be composited. r.Refraction.Blur 0 avoids the problem.

What Type of Bug are you experiencing?

Rendering (Graphics / Niagara)

Steps to Reproduce

  1. Create a project with the next settings:
    • r.PostProcessing.PropagateAlpha=True (Alpha Output)
    • r.Substrate=True
    • r.Substrate.OpaqueMaterialRoughRefraction=True
    • r.Refraction.Blur=1
  2. Create a Substrate material. Set Blend Mode to Translucent. Set Refraction Method to Index of Refraction. Set the refraction value to 0.7 and Opacity to 0.7.
  3. Place a cube with that material in front of opaque geometry, for example a landscape.
  4. Place a SceneCapture2D that frames the cube against the opaque geometry.
  5. Set its Capture Source to Final Tone Curve HDR, and its render target to an RGBA8 target.
  6. Capture the scene and check the alpha channel of the render target.

Expected Result

The cube has a wrong Alpha (fully transparent) in the SceneCapture render target.

Observed Result

The alpha of the cube’s pixels is 1.0, which means “no coverage”. When the render is composited over another background, the cube and the geometry behind it both disappear.

Affects Versions

5.8
5.7

Platform(s)

Windows

Upload an image

Additional Notes

The fault is already present in Scene Color HDR, before post-processing. Post-processing, the capture source and the tonemapper are therefore not involved.

The following make no difference. Each one was measured:

  • Anti-aliasing method (TSR, FXAA, none)
  • r.Translucency.StandardSeparated
  • r.SeparateTranslucency
  • r.Refraction.Blur.TemporalAA
  • r.Refraction.OffsetQuality
  • Render resolution (480x270 and 1920x1080)
  • bAlwaysPersistRenderingState on the capture component
  • Primitive alpha holdout (r.Deferred.SupportPrimitiveAlphaHoldout is off in all tests)

A primary view that renders the same frame reports the material’s transmittance in the alpha instead
of 1.0, so the fault appears to be specific to the scene-capture path. This part is an observation
from image measurements, not from a GPU capture.

Suspected cause (hypothesis, not verified with a GPU capture)

DistortionRendering.cpp:560 creates the rough-refraction scene-colour mip chain with the format
PF_FloatR11G11B10, which has no alpha channel:

FRDGTextureDesc SceneColorMipchainDesc = FRDGTextureDesc::Create2D(
    SceneColorMip0Resolution, PF_FloatR11G11B10, FClearValueBinding::None, ...);

The distortion Apply pass binds that texture as SceneColorTexture
(DistortionRendering.cpp:897-898) and samples it (DistortApplyScreenPS.usf:173). A sample from a
texture without an alpha channel returns alpha 1. The Merge pass then writes the result, alpha
included, into scene colour.