acdream/tests/AcDream.App.Tests/Rendering
Erik b7d655bce7 fix(lighting): A7 Fix D round 2 — outdoor objects get NO torches (retail useSunlight gate) (#140)
The Holtburg meeting-hall facade washed out warm/bright vs retail. The round-1
checkpoint blamed torch REACH (acdream Falloff 6×1.3=7.8m vs a supposed retail
Falloff 4). That theory is WRONG, and this commit fixes the real cause.

Empirical (HoltburgTorchFalloffProbeTests, headless dat dump via the production
LightInfoLoader): the orange entrance torch (setup 0x020005D8) is raw dat
Falloff 6 and acdream reads it FAITHFULLY — there is no Falloff-4 torch anywhere
in Holtburg. Both clients read the same dat float, so reach was never inflated.

Decomp (read verbatim + corroborated by an independent adversarial workflow):
retail's per-object torch binder minimize_object_lighting (0x0054d480) is gated
in RenderDeviceD3D::DrawMeshInternal (0x0059f398) by `if (Render::useSunlight == 0)`.
The outdoor landscape stage runs useSunlightSet(1) (PView::DrawCells 0x005a485a,
before LScape::draw), so the building EXTERIOR shell — drawn via
DrawBlock→DrawSortCell→DrawBuilding→CPhysicsPart::Draw→DrawMeshInternal — is lit
by SUN + ambient ONLY; torches are SKIPPED. The static bake
(SetStaticLightingVertexColors 0x0059cfe0) is EnvCell-only. So retail NEVER
torch-lights outdoor objects. This exactly explains the isolation test (object
point lights OFF → building matches retail).

Fix: WbDrawDispatcher.ComputeEntityLightSet gates per-object torch selection on
the object being INDOOR (ParentCellId is an EnvCell, (id&0xFFFF)>=0x0100) via the
pure predicate IndoorObjectReceivesTorches. Outdoor objects (building shells with
null ParentCellId, outdoor scenery, outdoor creatures) keep the all-(-1) light
set ⇒ sun + ambient only = retail. The indoor "no sun" half is already handled by
the global sun-kill when the player is inside a cell (UpdateSunFromSky). No
dungeon regression: EnvCell statics get ParentCellId set (keep torches).

Divergence register: AP-37 (residual: acdream keys sun/torch on the object's own
cell + a per-frame player-inside sun-kill, vs retail's per-draw-stage useSunlight;
only matters for through-doorway look-ins). The round-1 CHECKPOINT got a RESOLVED
banner correcting the reach theory.

Tests: WbDrawDispatcherTorchGateTests (7), HoltburgTorchFalloffProbeTests (dat
dump). App 280/1skip, Core 1486/2skip green. Held at the visual gate — not merged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 23:56:49 +02:00
..
Wb fix(lighting): A7 Fix D round 2 — outdoor objects get NO torches (retail useSunlight gate) (#140) 2026-06-19 23:56:49 +02:00
CameraCollisionIndoorTests.cs T6 (BR-7) C3: per-cell shadow architecture - flood registration, building channel, per-cell query; b3ce505 stopgap DELETED (closes #99) 2026-06-11 14:37:50 +02:00
CameraCollisionUpdateViewerTests.cs feat(A): wire SweepEye to the verbatim update_viewer (start-cell + fallbacks) 2026-06-05 11:10:32 +02:00
CameraControllerTests.cs feat(camera): InputAction + DebugVM surface for retail chase camera 2026-05-18 20:04:34 +02:00
CellViewDedupTests.cs feat(render): indoor render WORKS — terminating portal flood + every-cell seal + look-in FPS 2026-06-07 10:14:43 +02:00
CellVisibilityFromRootTests.cs refactor(render): Stage 3 T3.1 — delete FindCameraCell AABB grace-frame fallback 2026-06-02 15:36:47 +02:00
CellVisibilityPortalPolygonsTests.cs fix(render): Phase U.2b — resolve reciprocal portal by other_portal_id (retail 433557) 2026-05-30 16:56:00 +02:00
ClipFrameAssemblerTests.cs feat(render): indoor render WORKS — terminating portal flood + every-cell seal + look-in FPS 2026-06-07 10:14:43 +02:00
ClipFrameLayoutTests.cs feat(render): Phase U.3 — GPU clip-plane gate (gl_ClipDistance), no-clip default 2026-05-30 17:27:30 +02:00
ClipPlaneSetTests.cs feat(render): indoor render WORKS — terminating portal flood + every-cell seal + look-in FPS 2026-06-07 10:14:43 +02:00
CornerFloodReplayTests.cs knife-edge port: polyClipFinish W=0 eye-plane clip + degenerate-view propagation; EyeInsidePortalOpening rescue DELETED 2026-06-11 21:44:23 +02:00
EntityClipTests.cs fix(render): R1 — repurpose the ParentCellId==null cell-gate bypass (#78) 2026-06-02 20:10:26 +02:00
HouseExitWalkReplayTests.cs #118: outdoor dynamics draw in the outside stage under interior roots - the house-exit clip+vanish was the SEAL z-killing the player 2026-06-11 16:49:29 +02:00
IndoorDrawPlanTests.cs feat(render): IndoorDrawPlan.ShellPass — every visible cell, no drawable filter (R1) 2026-06-06 21:59:26 +02:00
InteriorEntityPartitionTests.cs T1 (fused BR-2/3): retail frame order - dynamics last, punch+seal, shell chop deleted 2026-06-11 11:16:27 +02:00
Issue95DungeonFloodDiagnosticTests.cs test(#95): headless dungeon-flood diagnostic — measure visible-cell count on 0x0007 2026-06-13 18:52:00 +02:00
Issue113DrawingBspFilterTests.cs fix(render): #113 root cause #2 - GfxObj meshes draw only DrawingBSP-referenced polys (the REAL phantom staircase) 2026-06-10 20:52:52 +02:00
Issue113MeetingHallFloodTests.cs fix(render): #113 - enable GL clip distances for the PView shell pass (phantom exterior staircase) 2026-06-10 16:26:55 +02:00
Issue120ReciprocalPingPongTests.cs #119-residual: tower-ascent harness pins the roof-lip flood gap; barrel claim RETRACTED (user axiom: not in retail) 2026-06-11 18:34:45 +02:00
Issue124LookInSeedRegionTests.cs fix #124: interior-root building look-ins as a landscape-stage sub-pass 2026-06-12 15:59:29 +02:00
Issue127FloodFlipReplayTests.cs close #127 (user-gated + desk pin): distant-building flood flap died with the W=0 clip port 2026-06-13 10:03:33 +02:00
Issue129PunchBiasTests.cs fix #129: cap the punch mark bias's eye-space reach (was unbounded at distance) 2026-06-12 13:38:59 +02:00
Issue130DoorwayStripTests.cs fix #130 (the real strip): drawn-shell lift vs draw-space portal consumers 2026-06-12 14:28:16 +02:00
Issue131SetupProbeTests.cs fix #131 (root cause 4, structurally forced): look-in cells draw their DYNAMICS - the town portal is a server object in the hall's porch cell 2026-06-12 20:52:34 +02:00
NdcScissorRectTests.cs fix #130: doorway-slice scissor cut the aperture's top/right pixel row 2026-06-12 13:31:43 +02:00
OutdoorCellNodeTests.cs feat(render): R-A2 — per-building floods (the flap fix) 2026-06-08 18:44:43 +02:00
PhysicsCameraCollisionProbeTests.cs feat(A): wire SweepEye to the verbatim update_viewer (start-cell + fallbacks) 2026-06-05 11:10:32 +02:00
PortalProjectionTests.cs knife-edge port: polyClipFinish W=0 eye-plane clip + degenerate-view propagation; EyeInsidePortalOpening rescue DELETED 2026-06-11 21:44:23 +02:00
PortalViewTests.cs feat(render): Phase A8.F — ViewPolygon + CellView clip-region data model 2026-05-29 11:30:28 +02:00
PortalVisibilityBuilderTests.cs knife-edge port: polyClipFinish W=0 eye-plane clip + degenerate-view propagation; EyeInsidePortalOpening rescue DELETED 2026-06-11 21:44:23 +02:00
PortalVisibilityRobustnessTests.cs feat(render): R-A2 — per-building floods (the flap fix) 2026-06-08 18:44:43 +02:00
RetailChaseCameraTests.cs fix(render): Part 1 — camera boom convergence snap (kills the at-rest viewer-cell flicker trigger) 2026-06-05 15:56:04 +02:00
ScreenPolygonClipTests.cs feat(render): Phase A8.F — ScreenPolygonClip 2D convex-polygon intersection 2026-05-29 11:37:30 +02:00
TerrainCullOrientationTests.cs fix #108-residual (root cause): terrain drew DOUBLE-SIDED - port retail landPolysDraw eye-side gate as terrain backface cull 2026-06-12 22:05:31 +02:00
TowerAscentReplayTests.cs #119-residual ROOT CAUSE: the +0.02 m render lift leaked into the portal-visibility graph - horizontal portals side-culled anyone standing on them 2026-06-11 19:26:06 +02:00