Revert "feat(render): Phase A8 RR7 — WB RenderInsideOut Steps 1-4 + outdoor branch"
This reverts commit 3d28d701a2.
This commit is contained in:
parent
21dc72b010
commit
4fa3390592
1 changed files with 16 additions and 167 deletions
|
|
@ -36,11 +36,6 @@ public sealed class GameWindow : IDisposable
|
||||||
private AcDream.App.Rendering.Wb.EntitySpawnAdapter? _wbEntitySpawnAdapter;
|
private AcDream.App.Rendering.Wb.EntitySpawnAdapter? _wbEntitySpawnAdapter;
|
||||||
private AcDream.App.Rendering.Vfx.EntityScriptActivator? _entityScriptActivator;
|
private AcDream.App.Rendering.Vfx.EntityScriptActivator? _entityScriptActivator;
|
||||||
private AcDream.App.Rendering.Wb.WbDrawDispatcher? _wbDrawDispatcher;
|
private AcDream.App.Rendering.Wb.WbDrawDispatcher? _wbDrawDispatcher;
|
||||||
/// <summary>Phase A8 RR7 (2026-05-26): portal stencil pipeline for the indoor
|
|
||||||
/// render branch (WB RenderInsideOut Steps 1-4). Non-null after OnLoad. Null
|
|
||||||
/// only if shader compilation failed — in which case the indoor branch falls
|
|
||||||
/// through to the outdoor path (graceful degradation, no crash).</summary>
|
|
||||||
private AcDream.App.Rendering.IndoorCellStencilPipeline? _indoorStencilPipeline;
|
|
||||||
/// <summary>Phase N.5: ARB_bindless_texture + ARB_shader_draw_parameters
|
/// <summary>Phase N.5: ARB_bindless_texture + ARB_shader_draw_parameters
|
||||||
/// support. Required at startup — missing bindless throws
|
/// support. Required at startup — missing bindless throws
|
||||||
/// <see cref="NotSupportedException"/> in <c>OnLoad</c>.</summary>
|
/// <see cref="NotSupportedException"/> in <c>OnLoad</c>.</summary>
|
||||||
|
|
@ -1765,23 +1760,6 @@ public sealed class GameWindow : IDisposable
|
||||||
_classificationCache);
|
_classificationCache);
|
||||||
// A.5 T22.5: apply A2C gate from quality preset.
|
// A.5 T22.5: apply A2C gate from quality preset.
|
||||||
_wbDrawDispatcher.AlphaToCoverage = _resolvedQuality.AlphaToCoverage;
|
_wbDrawDispatcher.AlphaToCoverage = _resolvedQuality.AlphaToCoverage;
|
||||||
|
|
||||||
// Phase A8 RR7 (2026-05-26): portal stencil pipeline. Constructed
|
|
||||||
// immediately after WbDrawDispatcher — same GL context, same lifetime.
|
|
||||||
// Null-safe: if shader compilation throws, the indoor branch falls back
|
|
||||||
// to outdoor rendering (no crash; just no indoor/outdoor separation).
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_indoorStencilPipeline = new AcDream.App.Rendering.IndoorCellStencilPipeline(
|
|
||||||
_gl,
|
|
||||||
System.IO.Path.Combine(shadersDir, "portal_stencil.vert"),
|
|
||||||
System.IO.Path.Combine(shadersDir, "portal_stencil.frag"));
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"[A8] IndoorCellStencilPipeline failed to construct: {ex.Message}");
|
|
||||||
_indoorStencilPipeline = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase G.1 sky renderer — its own shader (sky.vert / sky.frag)
|
// Phase G.1 sky renderer — its own shader (sky.vert / sky.frag)
|
||||||
|
|
@ -6937,11 +6915,7 @@ public sealed class GameWindow : IDisposable
|
||||||
System.Math.Clamp(fogColor.Z, 0f, 1f),
|
System.Math.Clamp(fogColor.Z, 0f, 1f),
|
||||||
1f);
|
1f);
|
||||||
|
|
||||||
// Phase A8 RR7 (2026-05-26): stencil buffer cleared per-frame now that the
|
_gl!.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||||
// stencil pipeline is wired in. Previously not cleared because no rendering
|
|
||||||
// consumed stencil. Without this clear, bits from a prior frame's indoor
|
|
||||||
// branch could leak into an outdoor frame and gate visibility incorrectly.
|
|
||||||
_gl!.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);
|
|
||||||
|
|
||||||
// Phase N.6 slice 1: one-shot surface-format histogram dump under
|
// Phase N.6 slice 1: one-shot surface-format histogram dump under
|
||||||
// ACDREAM_DUMP_SURFACES=1. Zero cost when off.
|
// ACDREAM_DUMP_SURFACES=1. Zero cost when off.
|
||||||
|
|
@ -7055,31 +7029,6 @@ public sealed class GameWindow : IDisposable
|
||||||
var visibility = _cellVisibility.ComputeVisibility(camPos);
|
var visibility = _cellVisibility.ComputeVisibility(camPos);
|
||||||
bool cameraInsideCell = visibility?.CameraCell is not null;
|
bool cameraInsideCell = visibility?.CameraCell is not null;
|
||||||
|
|
||||||
// Phase A8 RR7 (2026-05-26): the single source of truth for
|
|
||||||
// "render the indoor branch." Strict PointInCell + the camera's
|
|
||||||
// cell must actually belong to a Building (not an outdoor cell
|
|
||||||
// or untagged dungeon cell). No grace.
|
|
||||||
//
|
|
||||||
// sky pre-scene, terrain, stencil pipeline, weather post-scene
|
|
||||||
// all gate on this flag below. The lenient cameraInsideCell flag
|
|
||||||
// is kept ONLY for the [vis] probe's side-by-side logging.
|
|
||||||
bool cameraInsideBuilding = visibility?.CameraCell is not null
|
|
||||||
&& CellVisibility.PointInCell(camPos, visibility.CameraCell)
|
|
||||||
&& visibility.CameraCell.BuildingId is not null;
|
|
||||||
|
|
||||||
// Phase A8 RR7: look up buildings containing the camera cell.
|
|
||||||
// The BuildingRegistry is keyed by landblock id in _buildingRegistries
|
|
||||||
// (per Code Structure Rule #2 — Core can't reference App types, so the
|
|
||||||
// registry lives on GameWindow, not on a Core struct).
|
|
||||||
IReadOnlyList<AcDream.App.Rendering.Wb.Building> camBuildings =
|
|
||||||
System.Array.Empty<AcDream.App.Rendering.Wb.Building>();
|
|
||||||
if (cameraInsideBuilding && visibility?.CameraCell is not null)
|
|
||||||
{
|
|
||||||
uint cameraLandblockId = visibility.CameraCell.CellId & 0xFFFF0000u;
|
|
||||||
if (_buildingRegistries.TryGetValue(cameraLandblockId, out var reg))
|
|
||||||
camBuildings = reg.GetBuildingsContainingCell(visibility.CameraCell.CellId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SPIKE 2026-05-26: A8 transition investigation. Lights up the
|
// SPIKE 2026-05-26: A8 transition investigation. Lights up the
|
||||||
// dormant RenderingDiagnostics.ProbeVisibilityEnabled flag (added
|
// dormant RenderingDiagnostics.ProbeVisibilityEnabled flag (added
|
||||||
// by Task 6 of the original A8 plan). Per-frame state captures:
|
// by Task 6 of the original A8 plan). Per-frame state captures:
|
||||||
|
|
@ -7194,11 +7143,7 @@ public sealed class GameWindow : IDisposable
|
||||||
// cylinder 0x01004C42/0x01004C44) need to overlay terrain
|
// cylinder 0x01004C42/0x01004C44) need to overlay terrain
|
||||||
// and entities to look volumetric — see the post-scene
|
// and entities to look volumetric — see the post-scene
|
||||||
// RenderWeather call further below.
|
// RenderWeather call further below.
|
||||||
//
|
if (!cameraInsideCell)
|
||||||
// Phase A8 RR7 (2026-05-26): gate changed from !cameraInsideCell
|
|
||||||
// to !cameraInsideBuilding. When indoors (inside a building), the
|
|
||||||
// sky is drawn stencil-gated in the indoor branch below (Step 4a).
|
|
||||||
if (!cameraInsideBuilding)
|
|
||||||
{
|
{
|
||||||
_skyRenderer?.RenderSky(camera, camPos, (float)WorldTime.DayFraction,
|
_skyRenderer?.RenderSky(camera, camPos, (float)WorldTime.DayFraction,
|
||||||
_activeDayGroup, kf, environOverrideActive);
|
_activeDayGroup, kf, environOverrideActive);
|
||||||
|
|
@ -7222,14 +7167,8 @@ public sealed class GameWindow : IDisposable
|
||||||
// Phase N.5b: wrap Draw in CPU stopwatch for [TERRAIN-DIAG] rollup
|
// Phase N.5b: wrap Draw in CPU stopwatch for [TERRAIN-DIAG] rollup
|
||||||
// (gated on ACDREAM_WB_DIAG=1, same env var as [WB-DIAG]). Stopwatch
|
// (gated on ACDREAM_WB_DIAG=1, same env var as [WB-DIAG]). Stopwatch
|
||||||
// is cheap; only the periodic Console.WriteLine is gated.
|
// is cheap; only the periodic Console.WriteLine is gated.
|
||||||
//
|
|
||||||
// Phase A8 RR7 (2026-05-26): skip initial terrain when inside a building.
|
|
||||||
// Terrain renders stencil-gated in Step 4b of the indoor branch below.
|
|
||||||
// The old "Conditional depth clear: if (cameraInsideCell)" is removed —
|
|
||||||
// the A8 indoor branch manages depth state through MarkAndPunch instead.
|
|
||||||
_terrainCpuStopwatch.Restart();
|
_terrainCpuStopwatch.Restart();
|
||||||
if (!cameraInsideBuilding)
|
_terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb);
|
||||||
_terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb);
|
|
||||||
_terrainCpuStopwatch.Stop();
|
_terrainCpuStopwatch.Stop();
|
||||||
// Multiply by 100 then divide by 100 in the diag print to keep
|
// Multiply by 100 then divide by 100 in the diag print to keep
|
||||||
// 0.01 µs precision in the long-typed sample buffer. Terrain Draw
|
// 0.01 µs precision in the long-typed sample buffer. Terrain Draw
|
||||||
|
|
@ -7239,6 +7178,13 @@ public sealed class GameWindow : IDisposable
|
||||||
_terrainCpuSampleCursor = (_terrainCpuSampleCursor + 1) % _terrainCpuSamples.Length;
|
_terrainCpuSampleCursor = (_terrainCpuSampleCursor + 1) % _terrainCpuSamples.Length;
|
||||||
MaybeFlushTerrainDiag();
|
MaybeFlushTerrainDiag();
|
||||||
|
|
||||||
|
// Conditional depth clear: when camera is inside a building, clear
|
||||||
|
// depth (not color) so interior geometry writes fresh Z values on top
|
||||||
|
// of the terrain color buffer. Exit portals show outdoor terrain color
|
||||||
|
// because we kept the color buffer. Matching ACME GameScene.cs pattern.
|
||||||
|
if (cameraInsideCell)
|
||||||
|
_gl!.Clear(ClearBufferMask.DepthBufferBit);
|
||||||
|
|
||||||
// L-fix1 (2026-04-28): pass the set of animated-entity ids so
|
// L-fix1 (2026-04-28): pass the set of animated-entity ids so
|
||||||
// the renderer keeps remote players / NPCs / monsters
|
// the renderer keeps remote players / NPCs / monsters
|
||||||
// visible even when their landblock rotates out of the
|
// visible even when their landblock rotates out of the
|
||||||
|
|
@ -7255,104 +7201,11 @@ public sealed class GameWindow : IDisposable
|
||||||
animatedIds.Add(k);
|
animatedIds.Add(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase A8 RR7 (2026-05-26): indoor / outdoor branch.
|
// N.5: WbDrawDispatcher is always non-null (modern path mandatory).
|
||||||
//
|
_wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum,
|
||||||
// Indoor (cameraInsideBuilding == true) — WB RenderInsideOut Steps 1-4:
|
neverCullLandblockId: playerLb,
|
||||||
// MarkAndPunch on camBuildings' exit portals
|
visibleCellIds: visibility?.VisibleCellIds,
|
||||||
// IndoorPass (cell mesh + statics + building shells)
|
animatedEntityIds: animatedIds);
|
||||||
// EnableOutdoorPass
|
|
||||||
// Stencil-gated sky (acdream enhancement)
|
|
||||||
// Stencil-gated terrain re-draw
|
|
||||||
// Stencil-gated OutdoorScenery
|
|
||||||
// DisableStencil
|
|
||||||
// LiveDynamic
|
|
||||||
//
|
|
||||||
// Outdoor (cameraInsideBuilding == false):
|
|
||||||
// Unchanged from pre-A8: single Draw(All).
|
|
||||||
// RenderOutsideIn (looking INTO cottage windows from outside)
|
|
||||||
// ships in RR11.
|
|
||||||
|
|
||||||
if (cameraInsideBuilding && _indoorStencilPipeline is not null
|
|
||||||
&& visibility?.CameraCell is not null
|
|
||||||
&& camBuildings.Count > 0)
|
|
||||||
{
|
|
||||||
if (AcDream.Core.Rendering.RenderingDiagnostics.ProbeVisibilityEnabled)
|
|
||||||
Console.WriteLine($"[vis] branch=indoor buildings={camBuildings.Count}");
|
|
||||||
|
|
||||||
// Steps 1+2: stencil bit 1 + far-depth at the camera-buildings'
|
|
||||||
// exit portals. Combine polygons from all containing buildings
|
|
||||||
// (usually 1, occasionally 2 in shared-cell scenarios).
|
|
||||||
int totalVerts = 0;
|
|
||||||
foreach (var b in camBuildings)
|
|
||||||
totalVerts += _indoorStencilPipeline.UploadBuildingPortalMesh(b);
|
|
||||||
// Note: UploadBuildingPortalMesh overwrites the VBO each call.
|
|
||||||
// For multi-building cases, the last call wins. Loop-uploading
|
|
||||||
// all polygons would require a different API; for now we use
|
|
||||||
// the existing pipeline pattern (mark+punch in one call), which
|
|
||||||
// matches WB's per-building iteration. See RR9 for the multi-
|
|
||||||
// building marking pattern.
|
|
||||||
|
|
||||||
var viewProjection = camera.View * camera.Projection;
|
|
||||||
_indoorStencilPipeline.MarkAndPunch(viewProjection);
|
|
||||||
|
|
||||||
// Step 3: IndoorPass with camera-buildings' cell scope.
|
|
||||||
var camCellIds = new HashSet<uint>();
|
|
||||||
foreach (var b in camBuildings)
|
|
||||||
foreach (var cid in b.EnvCellIds) camCellIds.Add(cid);
|
|
||||||
|
|
||||||
_wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries,
|
|
||||||
cellIds: camCellIds,
|
|
||||||
frustum: frustum,
|
|
||||||
neverCullLandblockId: playerLb,
|
|
||||||
animatedEntityIds: animatedIds,
|
|
||||||
set: AcDream.App.Rendering.Wb.WbDrawDispatcher.EntitySet.IndoorPass);
|
|
||||||
|
|
||||||
// Step 4: stencil-gated outdoor pass.
|
|
||||||
_indoorStencilPipeline.EnableOutdoorPass();
|
|
||||||
|
|
||||||
// Step 4a: stencil-gated sky (acdream enhancement).
|
|
||||||
// DepthMask off so sky color writes through punched depth=1.0
|
|
||||||
// without disturbing the depth buffer; depth stays at the punch
|
|
||||||
// value so the next step's terrain re-draw can win.
|
|
||||||
_gl!.DepthMask(false);
|
|
||||||
_skyRenderer?.RenderSky(camera, camPos, (float)WorldTime.DayFraction,
|
|
||||||
_activeDayGroup, kf, environOverrideActive);
|
|
||||||
_gl!.DepthMask(true);
|
|
||||||
|
|
||||||
// Step 4b: stencil-gated terrain re-draw.
|
|
||||||
_terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb);
|
|
||||||
|
|
||||||
// Step 4c: stencil-gated OutdoorScenery.
|
|
||||||
_wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum,
|
|
||||||
neverCullLandblockId: playerLb,
|
|
||||||
visibleCellIds: visibility.VisibleCellIds,
|
|
||||||
animatedEntityIds: animatedIds,
|
|
||||||
set: AcDream.App.Rendering.Wb.WbDrawDispatcher.EntitySet.OutdoorScenery);
|
|
||||||
|
|
||||||
// (Step 5 = RR9.)
|
|
||||||
|
|
||||||
_indoorStencilPipeline.DisableStencil();
|
|
||||||
|
|
||||||
// LiveDynamic — player, NPCs, dropped items.
|
|
||||||
_wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum,
|
|
||||||
neverCullLandblockId: playerLb,
|
|
||||||
visibleCellIds: visibility.VisibleCellIds,
|
|
||||||
animatedEntityIds: animatedIds,
|
|
||||||
set: AcDream.App.Rendering.Wb.WbDrawDispatcher.EntitySet.LiveDynamic);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (AcDream.Core.Rendering.RenderingDiagnostics.ProbeVisibilityEnabled)
|
|
||||||
Console.WriteLine("[vis] branch=outdoor");
|
|
||||||
|
|
||||||
// Outdoor: single Draw(All). N.5: WbDrawDispatcher is always
|
|
||||||
// non-null (modern path mandatory). RenderOutsideIn (looking
|
|
||||||
// INTO cottage windows from outside) ships in RR11.
|
|
||||||
_wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum,
|
|
||||||
neverCullLandblockId: playerLb,
|
|
||||||
visibleCellIds: visibility?.VisibleCellIds,
|
|
||||||
animatedEntityIds: animatedIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phase G.1 / E.3: draw all live particles after opaque
|
// Phase G.1 / E.3: draw all live particles after opaque
|
||||||
// scene geometry so alpha blending composites correctly.
|
// scene geometry so alpha blending composites correctly.
|
||||||
|
|
@ -7370,10 +7223,7 @@ public sealed class GameWindow : IDisposable
|
||||||
// half of retail's LScape::draw split — GameSky::Draw(1)
|
// half of retail's LScape::draw split — GameSky::Draw(1)
|
||||||
// fires after the DrawBlock loop. Same indoor gate as the
|
// fires after the DrawBlock loop. Same indoor gate as the
|
||||||
// sky pass: weather is suppressed inside cells.
|
// sky pass: weather is suppressed inside cells.
|
||||||
//
|
if (!cameraInsideCell)
|
||||||
// Phase A8 RR7 (2026-05-26): gate changed from !cameraInsideCell
|
|
||||||
// to !cameraInsideBuilding (consistent with sky pre-scene gate).
|
|
||||||
if (!cameraInsideBuilding)
|
|
||||||
{
|
{
|
||||||
_skyRenderer?.RenderWeather(camera, camPos, (float)WorldTime.DayFraction,
|
_skyRenderer?.RenderWeather(camera, camPos, (float)WorldTime.DayFraction,
|
||||||
_activeDayGroup, kf, environOverrideActive);
|
_activeDayGroup, kf, environOverrideActive);
|
||||||
|
|
@ -10712,7 +10562,6 @@ public sealed class GameWindow : IDisposable
|
||||||
_liveSession = null;
|
_liveSession = null;
|
||||||
_audioEngine?.Dispose(); // Phase E.2: stop all voices, close AL context
|
_audioEngine?.Dispose(); // Phase E.2: stop all voices, close AL context
|
||||||
_wbDrawDispatcher?.Dispose();
|
_wbDrawDispatcher?.Dispose();
|
||||||
_indoorStencilPipeline?.Dispose(); // Phase A8 RR7
|
|
||||||
_skyRenderer?.Dispose(); // depends on sampler cache; dispose first
|
_skyRenderer?.Dispose(); // depends on sampler cache; dispose first
|
||||||
_samplerCache?.Dispose();
|
_samplerCache?.Dispose();
|
||||||
_textureCache?.Dispose();
|
_textureCache?.Dispose();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue