docs(render): §10.6 — post-hoc lens verdicts (three PASS) and the landing-hygiene chunk; AD-17 particle clause corrected
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
6435655d73
commit
6989868c37
2 changed files with 90 additions and 1 deletions
|
|
@ -144,7 +144,7 @@ readiness/requeue adaptation. See
|
|||
| AD-13 | 1-second dedup window for identical system chat messages (retail has none) | `src/AcDream.Core/Chat/ChatLog.cs:29` | ACE dual-sends the same system text (0xF7E0 + 0x02EB) for back-compat; without dedup every line doubled (Phase J compromise) | Two genuinely distinct but textually identical system messages within 1 s collapse to one line where retail shows both | ACE dual-send 0xF7E0 + 0x02EB |
|
||||
| AD-15 | `IsEnv` masks low-16 of the cell id (`(Id & 0xFFFF) >= 0x100`) where retail tests the full id | `src/AcDream.Core/World/Cells/ObjCell.cs:25` | Every real prefixed EnvCell id has low-16 ≥ 0x100 and every outdoor cell ≤ 0x40 — identical answers for all real dat ids, works for both bare and prefixed forms | None for real dat data; a hypothetical convention-violating id would route to the wrong (BSP vs terrain) point-in-cell logic | `CObjCell::GetVisible` pc:308215 |
|
||||
| AD-16 | Building-flood gate is a CPU frustum test on each building's `PortalBounds` AABB; retail floods exactly when the shell draws and an aperture survives (no bounds constant anywhere) | `src/AcDream.App/Rendering/WorldRenderFrameBuilder.cs` (`RuntimeWorldFrameBuildingSource.Gather`) | Documented as the tight equivalent of the shell viewconeCheck for flood purposes (the FPS fix the Chebyshev≤1 hack approximated); per-portal admission still goes through BuildFromExterior's screen clip; missing-bounds buildings always flood (safe over-include) | A too-small/stale PortalBounds AABB means the interior never floods — doorway shows a hole/black aperture from outside (inverse of the vanishing-staircase class) | `DrawBuilding` 0x0059f2a0; `BSPPORTAL::portal_draw_portals_only` 0x53d870 |
|
||||
| AD-17 | **REWRITTEN 2026-09-03 at Campaign OVERHAUL v2 S3 chunk 4 (rounds `ff607a1e0` + `7df0b94c9`).** Only two GPU clips remain, both retail `PView::DrawCells` portal-polygon draws: the exit seals and the punch fans. Each carries ≤8 `gl_ClipDistance` half-planes per view region (`ClipPlaneSet.MaxPlanes`; `Render::copy_view` caps a view at 31 vertices). Overflow handling differs by consumer: a >8-edge exit-seal view uses its convex NDC AABB as a conservative four-plane gate (`WalkFrameDriver.AppendClipSlot`); a >8-edge or multi-polygon OUTSIDE view yields a zero-plane slice (`ClipFrameAssembler.AppendOutsideSlice`'s fallback: slot 0, empty `Planes`, `ScissorFallbacks` counted) and that view's punch fan draws UNCLIPPED. Retail CPU-clips its portal polygons exactly. The former union-AABB scissor fallback, the sky's doorway scissor bracket, the per-slice terrain/sky/weather clips, the TerrainClip UBO and `NdcScissorRect` are DELETED: sky, terrain, weather and particles are never GPU-clipped, matching retail (`LScape::draw` installs no view before any of them). | `src/AcDream.App/Rendering/ClipPlaneSet.cs:23`; `src/AcDream.App/Rendering/ClipFrameAssembler.cs` (`AppendOutsideSlice`); `src/AcDream.App/Rendering/Walk/WalkFrameDriver.cs` (`AppendClipSlot`); `src/AcDream.App/Rendering/RetailPViewPassExecutor.WalkLeaf.cs` (`DrawWalkPunchFan` reads `OutsideViewSlices[i].Planes`) | Vulkan's `VkPhysicalDeviceLimits::maxClipDistances` floor is 8; over-inclusion is the safe direction for a depth-only seal/punch (it can cover at most the whole aperture fan), under-inclusion is the bug class | A >8-edge exit-seal view seals its AABB instead of the exact polygon and a >8-edge outside view punches its whole fan — depth-only over-include with no color bleed (the former **#130** strip family died with the scissor); an interior root's aperture exactness now rests on the depth clear + exit seals + interior repaint, never on a GPU clip of the landscape | `ACRender::polyClipFinish` decomp:702749; `PView::DrawCells` 0x005a4840 portal_view slices; `Render::copy_view` 0x0054dfc0; `LScape::draw` 0x00506330 |
|
||||
| AD-17 | **REWRITTEN 2026-09-03 at Campaign OVERHAUL v2 S3 chunk 4 (rounds `ff607a1e0` + `7df0b94c9`).** Only two GPU clips remain, both retail `PView::DrawCells` portal-polygon draws: the exit seals and the punch fans. Each carries ≤8 `gl_ClipDistance` half-planes per view region (`ClipPlaneSet.MaxPlanes`; `Render::copy_view` caps a view at 31 vertices). Overflow handling differs by consumer: a >8-edge exit-seal view uses its convex NDC AABB as a conservative four-plane gate (`WalkFrameDriver.AppendClipSlot`); a >8-edge or multi-polygon OUTSIDE view yields a zero-plane slice (`ClipFrameAssembler.AppendOutsideSlice`'s fallback: slot 0, empty `Planes`, `ScissorFallbacks` counted) and that view's punch fan draws UNCLIPPED. Retail CPU-clips its portal polygons exactly. The former union-AABB scissor fallback, the sky's doorway scissor bracket, the per-slice terrain/sky/weather clips, the TerrainClip UBO and `NdcScissorRect` are DELETED: sky, terrain and weather are never GPU-clipped, matching retail (`LScape::draw` installs no view before any of them). The mesh and particle shaders KEEP a per-cell `clipRegions[aClipSlot]` input, but the walk feeds every ordinary part (`WbDrawDispatcher.WalkClassify.ResolvePartVisible` — a Boolean sphere test, whole-mesh slot 0) and every particle (`ParticleRenderer`'s `clipSlot` default 0) the no-clip slot, matching retail's `DrawMeshInternal` sphere test; that machinery is dormant in the walk path and live only for the non-walk flat path. | `src/AcDream.App/Rendering/ClipPlaneSet.cs:23`; `src/AcDream.App/Rendering/ClipFrameAssembler.cs` (`AppendOutsideSlice`); `src/AcDream.App/Rendering/Walk/WalkFrameDriver.cs` (`AppendClipSlot`); `src/AcDream.App/Rendering/RetailPViewPassExecutor.WalkLeaf.cs` (`DrawWalkPunchFan` reads `OutsideViewSlices[i].Planes`) | Vulkan's `VkPhysicalDeviceLimits::maxClipDistances` floor is 8; over-inclusion is the safe direction for a depth-only seal/punch (it can cover at most the whole aperture fan), under-inclusion is the bug class | A >8-edge exit-seal view seals its AABB instead of the exact polygon and a >8-edge outside view punches its whole fan — depth-only over-include with no color bleed (the former **#130** strip family died with the scissor); an interior root's aperture exactness now rests on the depth clear + exit seals + interior repaint, never on a GPU clip of the landscape | `ACRender::polyClipFinish` decomp:702749; `PView::DrawCells` 0x005a4840 portal_view slices; `Render::copy_view` 0x0054dfc0; `LScape::draw` 0x00506330 |
|
||||
| AD-18 | Aperture far-Z punch is two-pass stencil-gated with an invented mark bias: 0.0005 NDC capped to a 0.5 m EYE-SPACE span (`MarkBiasNdc`); retail's single DEPTHTEST_ALWAYS punch is safe only under painter's far→near order we don't have | `src/AcDream.App/Rendering/PortalDepthMaskRenderer.cs:149` | **#117** (2026-06-11): the unconditional punch erased nearer occluders, painting interiors through them; the two-pass form is the z-buffered equivalent of retail's ordering safety. **#129** (2026-06-12): the constant-NDC bias spanned ~190 m of eye depth at a landblock (non-linear depth) → distant occluders punched; the eye-space cap bounds the reach (`Issue129PunchBiasTests`). DO-NOT-RETRY: punch must stay depth-gated (ISSUES #108) | Door-plane-hugging geometry beyond the 0.5 m cap re-occludes the aperture (a **#108**-class regression at >10 m viewing range); an occluder within the cap in front of a distant aperture still punches through | `D3DPolyRender::DrawPortalPolyInternal` 0x0059bc90 (maxZ1=7 / maxZ2=6) |
|
||||
| AD-19 | Under outdoor roots, ALL dynamics draw in one z-buffered final pass; retail draws objects painter-ordered per landcell inside the landscape pass (interior roots route per **#118**) | `src/AcDream.App/Rendering/RetailPViewRenderer.cs:126` | The dynamics-drawn-LAST invariant is what makes the aperture depth punch safe (first BR-2 attempt punched after dynamics and erased the player, reverted `88be519`); z-buffer substitutes for painter's order on opaque geometry | Punch/seal correctness hinges on an ordering invariant — any pass added after DrawDynamicsLast, or alpha content needing painter order, gets erased inside apertures or composites wrong | `LScape::draw` → `DrawBlock` 0x005a17c0 → DrawSortCell pc:430124; `PView::DrawCells` 0x005a4840 |
|
||||
| AD-20 | Camera sweep fallback seeds the eye's `AdjustPosition` from the PLAYER's cell; retail re-seats at the sought eye's own tracked cell (rest of function is a verbatim `update_viewer` port) | `src/AcDream.App/Rendering/PhysicsCameraCollisionProbe.cs:97` | acdream's camera doesn't track the sought-eye's cell separately; the eye is near the player so the player-cell stab list is assumed to cover it | An eye outside the player cell's stab-list coverage (boundary corners, cross-landblock pull-back) seats in the wrong cell — and the viewer cell roots the whole render: one-frame wrong root (flap-class flash) | `SmartBox::update_viewer` 0x00453ce0, pc:92878-92883 |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue