fix(render): Phase A8 — LiveDynamic in indoor branch + cull A/B gate
Two changes from visual-gate-#2 evidence. LiveDynamic fix (real bug closure): The user reported "can't see char ... door is missing" in visual gate #2. Doors and the player char are LiveDynamic entities (ServerGuid != 0). The outdoor branch's Draw(set: All) includes them; the indoor branch's RenderInsideOutAcdream only renders IndoorPass + OutdoorScenery partitions, implicitly excluding LiveDynamic. The method's own header comment promised "LiveDynamic is drawn last in BOTH branches" but no call existed in the indoor path — a documented behavior with no implementation. Wire the LiveDynamic Draw after RenderInsideOutAcdream returns with stencil + state restored to defaults at its cleanup block. Cull A/B diagnostic (bisect floor-missing root cause): ACDREAM_A8_DISABLE_CULL=1 forces every cell-mesh batch's effective CullMode to None. The visual-gate-#2 audit confirmed cell meshes upload correctly (every cell has multi-batch render data with non-zero indices, no null data, no zero handles). Every batch uniformly reports CullMode.Landblock which maps to glCullFace(Back) — identical to WB's mapping. So data is fine and CullMode lookup is fine; only the BIND-TIME interaction (polygon winding orientation in our coord system + cull-back) could still hide specific polys. If floor appears with this gate set, cull/winding is the remaining bug (need to either invert winding upstream or remap CullMode); if not, the issue is elsewhere (lighting / depth / alpha) and we look there. Tight bisect — one launch's evidence. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
772d69c7a6
commit
b19f3c14a9
2 changed files with 30 additions and 0 deletions
|
|
@ -7361,6 +7361,22 @@ public sealed class GameWindow : IDisposable
|
||||||
camBuildings, otherBuildings,
|
camBuildings, otherBuildings,
|
||||||
camera, frustum, playerLb, animatedIds,
|
camera, frustum, playerLb, animatedIds,
|
||||||
visibility?.VisibleCellIds);
|
visibility?.VisibleCellIds);
|
||||||
|
|
||||||
|
// Phase A8 fix (2026-05-28 visual-gate-#2 follow-up): LiveDynamic
|
||||||
|
// entities (player char, NPCs, dropped items, doors) were missing
|
||||||
|
// inside buildings because RenderInsideOutAcdream only renders the
|
||||||
|
// IndoorPass + OutdoorScenery partitions; LiveDynamic was implicitly
|
||||||
|
// excluded. The method's own header comment promised "LiveDynamic
|
||||||
|
// is drawn last in BOTH branches" but no call existed in the indoor
|
||||||
|
// path. Wire it here, after RenderInsideOutAcdream returns with
|
||||||
|
// stencil + state restored to defaults at its cleanup block. Same
|
||||||
|
// shape as the outdoor branch's Draw(All) for the LiveDynamic
|
||||||
|
// subset only.
|
||||||
|
_wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum,
|
||||||
|
neverCullLandblockId: playerLb,
|
||||||
|
visibleCellIds: visibility?.VisibleCellIds,
|
||||||
|
animatedEntityIds: animatedIds,
|
||||||
|
set: AcDream.App.Rendering.Wb.WbDrawDispatcher.EntitySet.LiveDynamic);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,16 @@ public sealed unsafe class EnvCellRenderer : IDisposable
|
||||||
private static uint _currentVao;
|
private static uint _currentVao;
|
||||||
private static CullMode? _currentCullMode;
|
private static CullMode? _currentCullMode;
|
||||||
|
|
||||||
|
// Phase A8 A/B diagnostic (2026-05-28 visual-gate-#2 follow-up):
|
||||||
|
// ACDREAM_A8_DISABLE_CULL=1 forces every batch's effective CullMode to
|
||||||
|
// None (no face culling). Used to isolate whether the missing-floor
|
||||||
|
// symptom is caused by polygon-winding+CullMode interaction or by
|
||||||
|
// something else (lighting, depth, alpha). If the floor appears with
|
||||||
|
// this set, cull/winding is the bug. If not, look elsewhere. Static
|
||||||
|
// because it's read once at startup; no need to re-query per draw.
|
||||||
|
private static readonly bool _forceCullModeNone =
|
||||||
|
string.Equals(Environment.GetEnvironmentVariable("ACDREAM_A8_DISABLE_CULL"), "1", StringComparison.Ordinal);
|
||||||
|
|
||||||
public bool NeedsPrepare { get; private set; } = true;
|
public bool NeedsPrepare { get; private set; } = true;
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
|
|
||||||
|
|
@ -987,6 +997,10 @@ public sealed unsafe class EnvCellRenderer : IDisposable
|
||||||
foreach (var group in batchesByCullMode)
|
foreach (var group in batchesByCullMode)
|
||||||
{
|
{
|
||||||
var cullMode = (CullMode)(group.Key % 4);
|
var cullMode = (CullMode)(group.Key % 4);
|
||||||
|
// A/B diagnostic: ACDREAM_A8_DISABLE_CULL=1 overrides every batch
|
||||||
|
// to no-culling. Reveals whether floor-missing is a cull/winding
|
||||||
|
// bug or something else.
|
||||||
|
if (_forceCullModeNone) cullMode = CullMode.None;
|
||||||
if (_currentCullMode != cullMode)
|
if (_currentCullMode != cullMode)
|
||||||
{
|
{
|
||||||
SetCullMode(cullMode);
|
SetCullMode(cullMode);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue