Fourteen numbered cases covering every way flat 2D and woven 3D can land on top of each other in an ordinary web page: translucent chrome, frosted glass, opaque plates, modals, nested scrollers, sticky tiles, tile-on-tile, and a mixed producer load. Two jobs in one page — a demo of what draw-order occlusion buys an author, and a standing hardware regression surface.
The second job constrains the first: nothing here is tuned to look
good. Cases that glitch today are built anyway and marked red on-page. A case softened
until it passes is not a regression test. Zero exclusion-era API is used — no
exclude(), no addGlobalOverlay(), no
data-inline3d-overlay: every 2D element below is an ordinary DOM sibling painted
after the canvas, and the page opens exactly one
createInline3D() session with autoChrome:false.
Reading order: straight through, 01–15. The full-tile frost pair (02, 03) spent a while in a red-bannered tail at the end, because browser#120 made them open the page with a screenful of frosted black; that shipped in 0.1.16, so they are back in place with their frost armed on load. Cases that were broken keep a short note saying what the failure looked like — that is the shape a regression would take, and it is the reason to keep judging them rather than to skip them.
Version floor: judged against 0.1.19 or newer. Cases 02, 03, 07 and 12 all assert behaviour that landed between 0.1.15 and 0.1.16, and 15 asserts a fix newer still — on an older browser they fail for a reason that is not a regression.
expected: the bar reads as crisp translucent 2D and the woven 3D shows through it at its designed opacity. No raw side-by-side anywhere, and no weave bleeding into the bar's text. This is the shipped page-header case, shrunk onto one tile.
expected, armed (as shipped): the frost reads crisp, with flat (mono, un-woven) tile content behind it — the D′ contract, where a backdrop filter is a function of what is behind it. Flat means the tile’s own content in 2D, not empty: what the glass blurs is a mono draw of the tile, made at the canvas quad’s own place in the page raster. The control tile above the strip stays 3D.
expected, disarmed: the panel is plain translucent 2D and all three tiles under it weave normally, exactly like case 01.
Was broken, now fixed — which is exactly why it is still here. Until the mono-under-frost draw landed (browser#120, shipped 0.1.16) this strip went to a blurred veil over black: inside a frost rect the frame held neither the tile’s canvas (suppressed once the tile joins) nor the woven draw-back (D′ clips the weave out of every frost rect), so the blur had nothing to sample. A return of that black veil is the regression this case catches — hence the frost is now armed on load rather than opt-in.
backdrop-filter: blur(14px)expected, armed (as shipped): a clean boundary down the panel’s left border — frosted-flat inside, woven 3D outside, on the same tile, with no shimmer or seam-crawl while scrolling. Inside the frost the tile reads as its own content in mono, not as a dark patch: that is the same mono-under-frost draw case 02 checks, here judged against a live 3D half of the very same tile, which is the strictest place to see it.
expected, disarmed: a translucent panel overhanging the tile’s right half; the whole tile weaves, and the panel’s left border is just a 2D edge.
expected: both plates render as fully opaque 2D over live 3D. The hover plate appears and disappears with no flash of raw side-by-side and leaves no hole behind it when it goes.
Hover the tile to raise the second plate.
expected: the scrim dims the tile as translucent 2D while the tile keeps weaving under it; the card is crisp. Dismissing restores the tile immediately — no stale dark rectangle. This is a page-DOM occluder, not a browser popup.
scripted: __showcase.modal(true)
expected: start the thrash, then scroll this section through the viewport. Every plate appears and vanishes cleanly — no stuck hole, no tile dropping to raw side-by-side, no plate woven into the tile content.
~10 Hz display toggle · scripted:
__showcase.thrash(true)
expected: walk the tile through 10 / 30 / 50 / 70 / 90 % visibility at the top and bottom edges (vertical leg), then at the left and right edges (horizontal leg). At every mark the visible part must weave correctly — no raw side-by-side, no stretch, no eye swap. A tile whose id-join works should weave at any nonzero visibility.
This is
browser#117’s
acceptance surface, and since that landed (0.1.15) the bar is two-sided: at every mark the
visible part either weaves correctly or does not weave at all — a tile whose canvas the
compositor could not join is now withheld from the weave and drawn by the page like any
2D element. What must never appear is a third outcome: raw side-by-side, or page chrome coming
back interlaced. Before 0.1.15 anything under roughly 70 % showed raw side-by-side. The
page’s sticky header is frosted so the top-edge leg runs under a bar that reaches the
compositor through its own render pass — judge this case with header: frosted on,
and flip it to solid only to attribute a failure. The ruler ticks sit in the gutters, never
on the tile: a hairline painted over the tile would add a 2D-over-3D composition on top of
the thing being measured.
Horizontal leg. Parking a tile off the
left or right viewport edge needs horizontal scroll, so this leg is a
full-bleed overflow-x:auto strip whose own edges are the viewport edges.
It therefore also carries a little of case 08's nested-scroll flavour — attribute a failure
here accordingly.
overflow:auto panelexpected: the weave rect tracks the inner scroll, not the page. The tile clips exactly at the panel's edges, never paints outside them, and never ghosts at a stale position after the inner scroll stops.
expected: the pinned tile weaves at its pinned position the whole
way. Cards at z-index:1 pass behind it (hidden); cards at
z-index:20 pass over it as crisp 2D. Draw order decides — not who is 3D.
expected: press Ctrl + +/−
by hand across the range. The weave rect stays registered with the CSS box, stereo stays square
(no squeeze), and the bar and badge stay on their pixels at every step.
Browser zoom is a user gesture — nothing here can drive it, so this section is an ordinary composed fixture (tile + translucent bar + frosted badge) that you zoom manually.
expected: both tiles weave, the shared border is a clean line, and
neither tile bleeds a column of the other's eye across it. Heights are matched exactly and
both boxes are square, so neither is squeezed. Corner radius is 0 on this whole
page precisely so this seam can be judged.
expected: topmost wins, and both tiles stay 3D. Where the upper tile covers the lower one the upper tile’s content is what weaves; everywhere the lower tile is still visible it keeps weaving its own — including the parts beside and below the overlap, not just a full-width band. No eye swap on either tile, no garble in the overlap, and the non-overlapping regions of both must be correct 3D.
Tile-over-tile is defined now: the compositor subtracts the upper tile’s rect from the lower one by paint order (browser#131, shipped 0.1.16) and then re-packs what the lower tile still owns piece by piece (#143), which is what keeps a corner occluder from flattening the whole tile. This case was the forcing function for that definition and now guards it.
expected: strict draw order through three layers — tile A woven at the bottom, the 2D card crisp over it, tile B woven over the card. No layer swallows the one above it.
expected: a live three.js scene, a side-by-side video and two still photos weave simultaneously in one viewport — all 3D, none falling back to mono or raw side-by-side, video playback smooth. This is the producer-weight mix that has historically pushed a session into its degraded path.
addScene() — a live three.js turntable, rendered twice per frame
into the two eye viewports.
addImage() — a still side-by-side photo.
addImage() — a second still, so the mix is not two producers.
addVideo() — a VP9/WebM side-by-side clip (640×360 per eye).
expected: press park under the bar. The tile scrolls up until nothing of it clears the bar, and at that moment the bar must stay crisp, ordinary 2D — especially its small text. Scroll back and the tile resumes weaving immediately. What must never happen is the bar’s own glyphs coming back interlaced.
Not a bigger case 04, and deliberately not a plate. A static opaque plate
over a tile does not reproduce this — measured on hardware, the canvas layer keeps
drawing. It takes a bar that is both sticky and truly opaque, with the tile
scrolled until nothing of it is left showing: only then does the compositor drop the fully
occluded canvas layer from the drawn layer list, so it emits no quad at all, nothing
resolves, and — on a page where no other tile resolved either — the weave fell through to
snapshotting the page and weaving the bar’s own pixels
(browser#167, reported
as the words in a shop’s sticky header interlacing as a product stage scrolled up under it).
Alpha exactly 1 is the trigger: this page’s own header: solid is
rgba(16,17,22,.94) and does not occlude, which is why nothing here reached the
state before. And the scroll is the PAGE’s, not a nested panel’s — a tile in an
overflow:auto container loses its join to
#164 (see case 08)
long before it is covered, which would fail this case for an unrelated reason.
The scrim behind this card is ordinary translucent 2D. The tile keeps weaving under it and must show through at the scrim's opacity; this card must stay crisp. Dismiss and the tile returns immediately.