Disabling the depth test to force a panel on top wrecks the whole scene
Aliases: always-on-top HUD · ignore Z · overlay queue
What it is
A menu is hidden by a wall. The cheapest fix is to disable the depth test on that mesh so it always draws in front. Depth-test disable buys that always-on-top by letting the menu cut the near hand, the table edge, a shoulder, and everything else that should have covered it. One panel is “fixed”; the room’s front-to-back relations are rewritten. This is not the occasional reversed depth order — it is the depth pipeline clocking off for this object.
Why it happens
A depth test asks, per pixel, whether something nearer has already been written. Disabling it announces that this mesh is exempt and will always cover what is already in the buffer. In engines that is an old HUD habit: screen space had no world depth. Moved into spatial UI, the mesh still occupies a world pose, people still read it with occlusion and stereo, but its pixels behave like a sticker. Near volumes pass through its “body”. Z-fighting is gone, replaced by a stabler, more wrong “always in front”. People may briefly explain it as a HUD; the explanation dies when a hand or a table edge is sliced, because a HUD should not occupy a world coordinate that intersects the room. Always-on-top also breaks stereo matching: both eyes see a skin that is always in front, and disparity disagrees with the world distance the object claims.
Studying it
Take one panel that must “not be hidden by the wall” and compare three implementations: depth test off, occlusion-aware repositioning, and a true head-locked layer with no world pose. Have people reach, walk around, and watch someone pass.
Independent variables: depth test on or off, whether the panel still has a world pose, presence of near-field hands and furniture. Dependent variables: count of near objects sliced, accuracy of depth-order judgements, a rating of whether the scene still coheres, false treatment of the panel as a pin-able wall or a grabbable object.
A single frame of the depth buffer confirms whether the test is off — inspect that implementation before collecting subjective scores.
Where it stops holding
A true screen-space layer (a calibration reticle, system battery) that clearly occupies no world can disable the depth test, provided its silhouette does not cut near objects, or it is drawn only in a small central patch. In an empty void with no near volumes the damage is unmeasurable. On optical see-through the depth test never governed real light, so on/off does not change “can it hide the window”, but it will still slice virtual hands and virtual furniture. Debug world-axes that sit always in front should not ship.
Applying it
- For a world panel that must not be hidden by the environment: move it or shrink it. Do not disable the depth test.
- Elements that must stay in front become an explicit head-locked layer with a limited silhouette, so they do not cut hands and table edges.
- In code review, treat DisableZTest / overlay-queue as a forbidden default on spatial meshes; allow only registered screen-space exceptions.
- How to check: open the panel, put a hand between it and the eye, then walk to its side. A hand or furniture sliced by the panel is always-on-top wrecking the scene; turning the depth test back on should remove the damage immediately.
Related
- Same group: N3.10.1 A hand clipping through a virtual object is the most glaring class of interpenetration · N3.10.3 Environment-depth accuracy sets how bad real–virtual clipping becomes · N3.10.4 Snapping a panel to a surface removes several clipping classes at once
- Nearby: N3.03 Depth Conflict · N3.06 Transparency and Occlusion
- Search terms:
depth-test disable·always-on-top·overlay queue