Skip to content

transform-style:preserve-3d — 3D scenes on desktop + mobile - #15

Merged
andrevanzuydam merged 1 commit into
mainfrom
feature/rendering-fidelity-9
Sep 17, 2026
Merged

andrevanzuydam merged 1 commit into
mainfrom
feature/rendering-fidelity-9

Conversation

@andrevanzuydam

Copy link
Copy Markdown
Owner

Builds transform-style: preserve-3d (per request: desktop and mobile).

What it does

A preserve-3d container renders its children as a real 3D scene instead of flattening to one quad. Paint3DScene (core) composes each child's 4×4 transform with the container's, projects the child's quad through the active perspective (vanishing point at perspective-origin), z-sorts back-to-front, and backface-culls (backface-visibility:hidden, via screen-winding flip). Each face is rasterised flat then warped onto its projected quad through the existing BeginLayer/EndLayer3D contract.

perspective/perspective-origin and transform-style/backface-visibility are parsed; the perspective context is threaded through the paint recursion.

Mobile

The base EndLayer3D is a no-op and Android renders via the pure-Pascal raster canvas — so I implemented EndLayer3D there (compositor WarpQuad → premultiplied warp → BlendPixel). 3D scenes now render on iOS + Android as well as macOS/Windows. Linux X11 has no CTM, so 3D stays flat there (documented). iOS + Android cross-compiles green.

Verification (pixel-matching headless Chrome)

  • Card-flip (front/back + backface cull), rotateY(50°) projection (edge deltas 0,0,0,0), 6-face cube (identical faces + z-order).
  • Reftest css-preserve3d-flip 0.00%; raster golden preserve3d 0.00% (the Android path).
  • Compliance 216/216, raster 11/11, DOM + interaction pass, leak-clean 30× on the cube. Chrome sweep: 0 unexpected failures.

Coverage now 134 ✅ · 3 🟡 · 0 📦 · 0 ❌ — zero parsed-only/missing properties remain.

🤖 Generated with Claude Code

A `transform-style: preserve-3d` container now renders its children as a
real 3D scene instead of flattening to one quad:

- Paint3DScene (core) composes each child's 4×4 transform with the
  container's, projects the child's quad through the active `perspective`
  (vanishing point at perspective-origin), z-sorts the planes back-to-
  front and backface-culls (screen-winding flip) faces with
  `backface-visibility:hidden`. Each face is rasterised flat then warped
  onto its projected quad via the existing BeginLayer/EndLayer3D contract.
- The `perspective`/`perspective-origin` properties and
  `transform-style`/`backface-visibility` are parsed; the perspective
  context is threaded through the paint recursion.
- **Mobile:** implemented `EndLayer3D` on the pure-Pascal raster canvas
  (compositor `WarpQuad` → premultiplied warp → `BlendPixel` composite),
  so 3D scenes render on Android (and the raster golden path), matching
  the Cocoa/iOS shells. Linux X11 has no CTM, so 3D stays flat there.
- @supports now reports perspective / transform-style / 3D transforms
  as supported (dropped two stale "not projected" checks).

Card-flip (front/back + backface cull) and a 6-face cube verified
pixel-matching headless Chrome. Reftest css-preserve3d-flip (0.00%),
raster golden preserve3d (0.00%, the Android path). DOM, compliance
216/216, raster 11/11, interaction, leak-clean over 30 cycles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@andrevanzuydam
andrevanzuydam merged commit 64f4fc9 into main Sep 17, 2026
3 checks passed
@andrevanzuydam
andrevanzuydam deleted the feature/rendering-fidelity-9 branch September 17, 2026 13:10
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