From 9bff2b046267aed4ff5267aeb5ca15706852f0aa Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 31 May 2026 21:50:07 +0200 Subject: [PATCH] docs: render-pipeline SSOT section + #78 reset pointer (redo of edits that silently failed) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The architecture and ISSUES edits in the prior commit (0013819) failed silently because they were anchored on the session-reminder's rendering of the files, not the real text. Redone against actual content: - architecture doc: new 'Render Pipeline (SSOT)' section — the 3-gate patchwork vs the unified-PView target + the one rule (compute visibility once, enforce it once). - ISSUES #78: promoted to the render-architecture-reset target; points to the canonical handoff + the architecture section. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/ISSUES.md | 14 +++++++ docs/architecture/acdream-architecture.md | 45 +++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/docs/ISSUES.md b/docs/ISSUES.md index b567624..54fbc6b 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -358,6 +358,20 @@ terrain by indoor-cell visibility (port retail `CEnvCell::find_visible_child_cel [`docs/research/2026-05-31-u4c-flap-fixed-and-residuals-handoff.md`](research/2026-05-31-u4c-flap-fixed-and-residuals-handoff.md) (residual 1). +**2026-05-31 (PM) — promoted to the RENDER ARCHITECTURE RESET target.** A week of +point-fixing produced no shippable indoor render. #78 is now understood as the visible +symptom of an architectural gap, NOT a standalone bug: acdream enforces visibility via +THREE inconsistent gates (terrain `TerrainClipMode` / shell per-cell clip / entity +`ParentCellId` filter with a `ParentCellId==null` outdoor-stab bypass) instead of retail's +ONE PView gate. Direct evidence (`[shell]` probe, `ACDREAM_PROBE_SHELL`) RULED OUT every +other subsystem: the interior cell shells render fine (geometry/texture/opaque/depth +correct); the residual is purely that outdoor geometry isn't gated to portal openings +when indoors. The fix is the unified PView gate (one traversal → one gate for ALL +geometry), which closes #78 + transparent walls + grey enclosure together. **Canonical +(read first):** +[`docs/research/2026-05-31-render-architecture-reset-handoff.md`](research/2026-05-31-render-architecture-reset-handoff.md) ++ the "Render Pipeline" section of `docs/architecture/acdream-architecture.md`. + --- ## #79 — Indoor lighting: spurious spot lights on walls diff --git a/docs/architecture/acdream-architecture.md b/docs/architecture/acdream-architecture.md index 2ada332..477dcc2 100644 --- a/docs/architecture/acdream-architecture.md +++ b/docs/architecture/acdream-architecture.md @@ -311,6 +311,51 @@ The plugin API exposes them as `WorldEntitySnapshot`. GameWindow becomes thin. --- +## Render Pipeline (SSOT — current state + unified-PView target) + +> **The per-frame render step above is STALE** (it names deleted classes +> `TerrainRenderer` / `StaticMeshRenderer`). The modern path (Phase N.5, mandatory) is +> `WbDrawDispatcher` (entities) + `EnvCellRenderer` (indoor cell shells) + +> `TerrainModernRenderer` (terrain), fed by the portal-visibility stack. This section is +> the authoritative description of how indoor/outdoor rendering is *supposed* to work and +> where the code currently diverges. Canonical reset handoff: +> `docs/research/2026-05-31-render-architecture-reset-handoff.md`. + +**The principle (retail PView).** acdream must render the world the way retail does — +through **one** portal-visibility traversal whose output **gates every geometry type +uniformly**. From the player's cell, walk the portal graph; each visible cell carries a +screen-space clip region (its portal opening, recursively intersected); the **outside** +(terrain + outdoor scenery) is reached only through **exit portals** and is clipped to +those openings. Interior cell shells, interior statics, and the outside are **all** +clipped to their PView region. This is why retail is **seamless by construction**. Decomp +anchors: `PView::ConstructView` (`:433750`), `InitCell` (`:432896`), `DrawCells` +(`:432715`), `CEnvCell::find_visible_child_cell` (`:311397`), `SmartBox::update_viewer` +(`:92761`). Reference port acdream owns but never invokes: WB `RenderInsideOut` / +`VisibilityManager`. + +**The one rule:** *compute visibility once; enforce it once, for all geometry.* Indoors, +you see the outside **only** through portal openings (clipped); an empty outside-view +(windowless interior) draws **no** outdoor geometry. Outdoors, the gate is "everything." + +**Current divergence (the patchwork — what the reset must fix).** acdream computes the +visibility correctly (`CellVisibility.ComputeVisibility` → `PortalVisibilityBuilder.Build`, +a `ConstructView` port → `ClipFrameAssembler`) but then **enforces it three different, +inconsistent ways**: +1. `TerrainModernRenderer` — gated by `TerrainClipMode {Skip|Scissor|Planes}` (the Scissor + fallback over-includes). +2. `EnvCellRenderer` — gated by the per-cell clip slot (≈correct; the shells DO render — + proven by the `[shell]` probe, `ACDREAM_PROBE_SHELL`). +3. `WbDrawDispatcher` — gated by `ParentCellId ∈ visibleCellIds`, **but outdoor stabs + (`ParentCellId==null`) bypass the gate** → outdoor scenery/terrain shows from inside + (issue #78). + +Three gates that must agree but don't → structural seams (transparent walls, +terrain-through-floor, grey enclosure). **The reset consolidates them into the single +PView gate** (outside content clipped to the `OutsideView` region; no `ParentCellId==null` +bypass; no Scissor over-include). This is a **consolidation of existing machinery** +(`PortalVisibilityBuilder` + `ClipFrame`), not a rewrite. Do NOT add a fourth special-case +gate to mask a seam — that anti-pattern produced the patchwork. + ## Roadmap Model The old R1-R8 architecture sequence was a useful early refactor sketch, but it