Skip to content

docs(depth-budget): the content mask is the UNCLIPPED silhouette (v4, runtime#1470) - #325

Merged
dfattal merged 1 commit into
mainfrom
docs/depth-budget-v4-mask-invariant
Sep 15, 2026
Merged

dfattal merged 1 commit into
mainfrom
docs/depth-budget-v4-mask-invariant

Conversation

@dfattal

@dfattal dfattal commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Comments and prose only — no behaviour change, no binary rebuilt. (native~/build-mac.sh was run to confirm the header still compiles; the resulting bundle was reverted so the diff stays docs-only.)

Why

XR_DXR_depth_budget spec v4 (DisplayXR/displayxr-runtime#1470, runtime PR #1471) says the content mask chained on xrEndFrame must be the silhouette the content would have at an unrestricted budget — rasterised ignoring the far clip. v3's wording ("its rendered silhouette") made the mask a function of the budget the runtime had just published, which closes a feedback loop on a completely static desktop:

clipped → small silhouette over a quiet patch of desktop → budget opens → rear half appears → silhouette grows across a text column → budget closes → rear half discarded → round again, ~0.6–1.1 s per cycle.

This plugin was never affected — and nothing said so

Audited the whole transparency path. The plugin consumes farOffsetVH (DisplayXRDepthBudget.cs:116-137_DXRRearOffset / dxr_prov_get_eye_clip), and chains both XrContentBoundsDXR (from Renderer.bounds, DisplayXRContentBounds.cs:221-234) and XrContentMaskDXR (DisplayXRTransparentOverlay.cs:1756-1760dxr_prov_set_content_mask). Neither region depends on the clip state:

  • the silhouette is a geometry rasterisationCommandBuffer.DrawRenderer of clickableRenderers with ZTest Always, Cull Off, and clip-space z pinned to mid-frustum, so no near/far plane can touch it — not an alpha readback of the rendered frame;
  • the depth-budget foreground clip is a separate fragment-discard pass over the camera's colour target and never runs over the mask RT;
  • nothing writes Camera.farClipPlane from the budget.

So the plugin already satisfies v4 by construction. But the obvious "optimisation" — reuse the post-clip swapchain alpha, which is exactly what displayxr-demo-modelviewer did — would silently reintroduce #1470, and the z pin was documented only as a click-through visual-clip fix.

What changed

  • Runtime/Resources/DisplayXRSilhouette.shader — name the readback's second consumer, and mark the z pin as load-bearing for both the click-through region and the v4 mask. Explicit: do not replace this pass with a post-clip alpha readback.
  • native~/displayxr_extensions.h — retire the v3 wording on XrContentMaskDXR for the v4 meaning; correct the "byte-identical to SPEC_VERSION 2" self-description (still byte-identical — the source of truth is now 4, and v4 moved no layout). XR_DXR_depth_budget_SPEC_VERSION stays 2 deliberately: it is the published minimum-runtime floor the drift audit reads, not the version transcribed.
  • CHANGELOG.md / CLAUDE.md — the mask and the click-through window region are not necessarily one artefact. The window region is about which pixels were painted, so post-clip alpha is right for it; they coincide here only because the shared producer is pre-clip geometry.
  • docs~/architecture/click-through-mask.md — a short section naming the mask's second consumer, with the two contracts side by side.

Testing

Comment/prose only, so there is nothing to exercise. native~/build-mac.sh builds clean. Untested: the Windows D3D12 provider cannot be compiled or run on the authoring box (macOS), and no Windows transparent Unity app was run against a v4 runtime — the v4-compliance verdict is static analysis of the C#, HLSL and native TU, not observed behaviour.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PJ8nDs4zBgjPKYwvAv4om4

… runtime#1470)

Comments and prose only - no behaviour change, no binary rebuilt.

XR_DXR_depth_budget spec v4 (DisplayXR/displayxr-runtime#1470) says the
content mask chained on xrEndFrame must be the silhouette the content WOULD
have at an unrestricted budget, rasterised ignoring the far clip. v3's wording
("its rendered silhouette") made the mask a function of the budget the runtime
had just published, which closes a feedback loop: clipped -> small silhouette
over a quiet patch of desktop -> budget opens -> rear half appears -> silhouette
grows over a busy patch -> budget closes -> round again, ~1 Hz on a completely
static desktop.

This plugin already satisfies v4 by construction and was never affected: the
silhouette pass rasterises PRE-CLIP GEOMETRY (CommandBuffer.DrawRenderer with
ZTest Always and clip-space z pinned to mid-frustum), and the depth-budget
foreground clip is a separate fragment-discard pass over the camera's colour
target. Nothing in the mask or bounds path reads the budget. But nothing said
so, and the obvious "optimisation" - reuse the post-clip swapchain alpha, which
is exactly what the modelviewer did - would silently reintroduce #1470. So:

- DisplayXRSilhouette.shader: name the second consumer of the readback, and mark
  the z pin as load-bearing for BOTH the click-through region and the v4 mask.
- displayxr_extensions.h: retire the v3 wording on XrContentMaskDXR for the v4
  meaning, and correct the "byte-identical to SPEC_VERSION 2" self-description
  (still byte-identical; the source of truth is now 4, and v4 moved no layout).
  The SPEC_VERSION floor stays 2 deliberately - it drives the published
  minimum-runtime requirement, not the version transcribed.
- CHANGELOG.md / CLAUDE.md: the mask and the click-through window region are not
  necessarily one artefact. The window region is about which pixels were
  painted, so post-clip alpha is right for it; they coincide here only because
  the shared producer is pre-clip geometry.
- docs~/architecture/click-through-mask.md: name the mask's second consumer, with
  the two contracts side by side and why this pipeline satisfies both.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJ8nDs4zBgjPKYwvAv4om4
@dfattal
dfattal merged commit c232be4 into main Sep 15, 2026
8 checks passed
@dfattal
dfattal deleted the docs/depth-budget-v4-mask-invariant branch September 15, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant