phase(N.5b): retire legacy terrain renderers

Deletes:
- TerrainChunkRenderer.cs (454 lines, replaced by TerrainModernRenderer)
- TerrainRenderer.cs (247 lines, older sibling, no production users)
- terrain.vert / terrain.frag (replaced by terrain_modern.{vert,frag})

Removes the temporary Task 8 perf-benchmark toggle (ACDREAM_LEGACY_TERRAIN
env var, _useLegacyTerrain field, parallel _terrainLegacy renderer
instance, [TERRAIN-DIAG/modern|legacy] label suffix). The modern path
is now the only path. Mirror N.5's mandatory-modern amendment: missing
GL_ARB_bindless_texture throws NotSupportedException at startup
(already in place via the BindlessSupport.TryCreate gate).

Three load-bearing research comments preserved verbatim from terrain.vert
into terrain_modern.vert before deletion: the MIN_FACTOR = 0.0 N-dot-L
floor block (cross-ref Lambert brightness split), the aPacked3 bit
layout, the gl_VertexID corner-table 2026-04-21 ConstructPolygons fix.

Also retires the now-orphaned _shader field (legacy terrain pipeline
was its only user).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-09 12:59:05 +02:00
parent da56063be5
commit 7dfa2af6c0
6 changed files with 31 additions and 1027 deletions

View file

@ -19,17 +19,8 @@ public sealed class GameWindow : IDisposable
private GL? _gl;
private IInputContext? _input;
private TerrainModernRenderer? _terrain;
// Phase N.5b benchmark toggle (TEMPORARY — removed in Task 9 along with TerrainChunkRenderer):
// when ACDREAM_LEGACY_TERRAIN=1, route Draw through the legacy renderer
// for direct perf comparison. Both renderers are constructed and fed
// AddLandblock/RemoveLandblock; only one is drawn per frame.
private TerrainChunkRenderer? _terrainLegacy;
private bool _useLegacyTerrain;
private Shader? _shader;
/// <summary>Phase N.5b: terrain_modern.vert/.frag program. Owned by
/// <see cref="_terrain"/> at draw time but allocated + disposed here. Lives
/// in parallel with <see cref="_shader"/> (legacy terrain.vert/.frag) until
/// Task 9 deletes the legacy renderer.</summary>
/// <see cref="_terrain"/> at draw time but allocated + disposed here.</summary>
private Shader? _terrainModernShader;
private CameraController? _cameraController;
private IMouse? _capturedMouse;
@ -985,13 +976,10 @@ public sealed class GameWindow : IDisposable
_gl.Enable(EnableCap.DepthTest);
string shadersDir = Path.Combine(AppContext.BaseDirectory, "Rendering", "Shaders");
_shader = new Shader(_gl,
Path.Combine(shadersDir, "terrain.vert"),
Path.Combine(shadersDir, "terrain.frag"));
// Phase N.5b: terrain_modern shader pair — bindless texture handles +
// glMultiDrawElementsIndirect dispatch path. Loaded in parallel with
// the legacy `_shader`; Task 9 will retire the legacy program.
// glMultiDrawElementsIndirect dispatch path. The only terrain shader
// since Task 9 retired the legacy terrain.vert/.frag program.
_terrainModernShader = new Shader(_gl,
Path.Combine(shadersDir, "terrain_modern.vert"),
Path.Combine(shadersDir, "terrain_modern.frag"));
@ -1451,10 +1439,6 @@ public sealed class GameWindow : IDisposable
_terrain = new TerrainModernRenderer(_gl, _bindlessSupport, _terrainModernShader!, terrainAtlas);
// Phase N.5b benchmark toggle (TEMPORARY — see field declaration).
_useLegacyTerrain = Environment.GetEnvironmentVariable("ACDREAM_LEGACY_TERRAIN") == "1";
_terrainLegacy = new TerrainChunkRenderer(_gl, _shader!, terrainAtlas);
int centerX = (int)((centerLandblockId >> 24) & 0xFFu);
int centerY = (int)((centerLandblockId >> 16) & 0xFFu);
@ -1612,7 +1596,6 @@ public sealed class GameWindow : IDisposable
_lightingSink.UnregisterOwner(ent.Id);
}
_terrain?.RemoveLandblock(id);
_terrainLegacy?.RemoveLandblock(id); // Phase N.5b benchmark toggle (TEMPORARY).
_physicsEngine.RemoveLandblock(id);
_cellVisibility.RemoveLandblock((id >> 16) & 0xFFFFu);
});
@ -4762,7 +4745,7 @@ public sealed class GameWindow : IDisposable
float localY = spawn.LocalPosition.Y;
// Prefer the physics engine's terrain sampler (TerrainSurface.SampleZ)
// — it uses the same AC2D render split-direction formula the
// TerrainChunkRenderer uses for the visible terrain mesh. This
// TerrainModernRenderer uses for the visible terrain mesh. This
// guarantees trees are placed on the SAME Z height the player
// walks on. If physics hasn't registered this landblock yet,
// fall back to the local bilinear sample.
@ -5133,7 +5116,6 @@ public sealed class GameWindow : IDisposable
var meshData = AcDream.Core.Terrain.LandblockMesh.Build(
lb.Heightmap, lbXu, lbYu, _heightTable, _blendCtx, _surfaceCache);
_terrain.AddLandblock(lb.LandblockId, meshData, origin);
_terrainLegacy?.AddLandblock(lb.LandblockId, meshData, origin); // Phase N.5b benchmark toggle (TEMPORARY).
// Step 4: drain pending LoadedCells from the worker thread.
while (_pendingCells.TryTake(out var cell))
@ -6358,11 +6340,7 @@ public sealed class GameWindow : IDisposable
// (gated on ACDREAM_WB_DIAG=1, same env var as [WB-DIAG]). Stopwatch
// is cheap; only the periodic Console.WriteLine is gated.
_terrainCpuStopwatch.Restart();
// Phase N.5b benchmark toggle (TEMPORARY): pick renderer per ACDREAM_LEGACY_TERRAIN.
if (_useLegacyTerrain)
_terrainLegacy?.Draw(camera, frustum, neverCullLandblockId: playerLb);
else
_terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb);
_terrain?.Draw(camera, frustum, neverCullLandblockId: playerLb);
_terrainCpuStopwatch.Stop();
// 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
@ -8788,7 +8766,7 @@ public sealed class GameWindow : IDisposable
double cpuMedUs = cpuMedHundredthsUs / 100.0;
double cpuP95Us = cpuP95HundredthsUs / 100.0;
Console.WriteLine(
$"[TERRAIN-DIAG{(_useLegacyTerrain ? "/legacy" : "/modern")}] cpu_us={cpuMedUs:F2}m/{cpuP95Us:F2}p95 " +
$"[TERRAIN-DIAG] cpu_us={cpuMedUs:F2}m/{cpuP95Us:F2}p95 " +
$"draws={_terrain?.VisibleSlots ?? 0}/frame " +
$"visible={_terrain?.VisibleSlots ?? 0} " +
$"loaded={_terrain?.LoadedSlots ?? 0} " +
@ -8843,8 +8821,6 @@ public sealed class GameWindow : IDisposable
_meshShader?.Dispose();
_terrain?.Dispose();
_terrainLegacy?.Dispose(); // Phase N.5b benchmark toggle (TEMPORARY).
_shader?.Dispose();
_terrainModernShader?.Dispose();
_sceneLightingUbo?.Dispose();
_particleRenderer?.Dispose();