Skip to content

Build-path silhouette aliasing: Unity drops MSAA on XR eye texture (Windows D3D12) #121

@dfattal

Description

@dfattal

Summary

In Build mode on Unity 6 + OpenXR 1.16.1 + D3D12 + Built-in RP + MultiPass, Unity creates the XR eye texture with msaaSamples=1 regardless of QualitySettings.antiAliasing. This produces binary alpha at silhouette edges in alpha-native transparent overlays — visible as hard aliasing on low-frequency-detail content. Textured assets (Mixamo tiger fur) hide it; flat-shaded characters expose it.

Evidence

Runtime probe attached to TransparentAutoSetup:

[MSAA Probe][frame N] QS.aa=8 XR.eye.msaa=1 XR.eye.dims=1920x1080 XR.eye.fmt=ARGB32 XR.eye.depth=32 XR.eye.eyeTexRes=1 XR.isDeviceActive=True
[MSAA Probe][frame N] cam 'Main Camera': allowMSAA=True stereoTargetEye=Both targetTexture=(none/default)
  • QualitySettings.antiAliasing = 8 ✓
  • Camera.allowMSAA = True ✓
  • HDR off on the camera ✓
  • Forward rendering path ✓
  • Eye texture format has alpha channel (ARGB32) ✓
  • But XRSettings.eyeTextureDesc.msaaSamples = 1

displayxr.log confirms Unity asks for samples=1 swapchain:

[DisplayXR] xrCreateSwapchain: format=28 size=1920x1080 samples=1

Why it's not a plugin bug

  • The plugin sets EnvironmentBlendMode = AlphaBlend correctly (Player.log confirms XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND (Selected)).
  • The runtime DP composes fractional alpha correctly when given soft alpha — verified independently with semi-transparent (alpha=0.5) test content.
  • The Preview-path equivalent of this issue was identified as a plugin bug and fixed in Fix(preview): MSAA atlas RT so silhouettes get fractional alpha #120 (the preview's atlas RT was created without MSAA via the no-MSAA RenderTexture constructor). The Build path has no equivalent code in the plugin — Unity's OpenXR loader creates the eye texture internally.

Reproduction

  1. displayxr-unity-test-transparent repo, scene CubeTest.unity with a flat-shaded character (e.g. ghost).
  2. QualitySettings.antiAliasing = 8, Camera.allowMSAA = true, HDR off, Forward path.
  3. Windows graphics API D3D12 (m_APIs: 12000000), Built-in RP, OpenXR 1.16.1.
  4. Build And Run for Windows Standalone.
  5. Silhouette edges are binary (no fractional alpha) — visible as stair-stepping.

Investigations ruled out

  • D3D11: separately broken (geometry corruption, plugin warns about it).
  • Vulkan: plugin lacks a Windows Vulkan backend (separate issue forthcoming).
  • HDR off, Forward path: doesn't change eye.msaa=1.
  • Camera-level allowMSAA = true: ignored by Unity's XR eye RT creation.

Workarounds

None known on the plugin side without significant work (camera render hook to MSAA RT + Blit-resolve into Unity's XR eye target — non-trivial, Unity manages the eye target opaquely). Most likely root cause is in UnityOpenXR.dll (Unity Technologies' native).

Next steps

  • Try Vulkan as graphics API (Unity OpenXR on Vulkan historically has different MSAA handling) — blocked on Vulkan-on-Windows backend support in the plugin (separate issue).
  • File Unity bug if Vulkan also doesn't engage MSAA.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions