fix(render): #100 — render terrain 1 cm below physical Z (retail zFightTerrainAdjust)

Subtract 0.01 from every terrain vertex Z in the modern terrain vertex
shader, matching retail's per-draw nudge applied inside
ACRender::landPolysDraw(arg2=2). Coplanar building floors now always win
the depth test against the rendered terrain, so the visual "ground at
the building floor" reads as the building's floor, not as Z-fighting.

Constant 0.01f bit-equals retail's float literal 0.00999999978 when
rounded to single precision.

Render-only — physics reads the un-nudged heightmap via
TerrainSurface.SampleZ / SampleZFromHeightmap. The same render-vs-
physics split is already established for EnvCell render lift
(+0.02m at GameWindow.cs around the cell-mesh draw).

Retail anchors:
  docs/research/named-retail/acclient_2013_pseudo_c.txt:1120769
  docs/research/named-retail/acclient_2013_pseudo_c.txt:702254

Cross-ref:
  docs/research/2026-05-25-issue-100-terrain-cutout-handoff.md
  docs/superpowers/plans/2026-05-25-issue-100-terrain-cutout.md

Followed by Task 2 (delete the hiddenTerrainCells / BuildingTerrainCells
plumbing). Visible result of this commit alone: building floors stop
Z-fighting, but the 24m x 24m transparent rectangles persist until the
plumbing is removed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-25 21:24:28 +02:00
parent 2fc312eac3
commit f48c74aa8b

View file

@ -136,5 +136,12 @@ void main() {
vRoad0 = unpackOverlayLayer(aPacked2.x, aPacked2.y, rotRd0, baseUV);
vRoad1 = unpackOverlayLayer(aPacked2.z, aPacked2.w, rotRd1, baseUV);
gl_Position = uProjection * uView * vec4(aPos, 1.0);
// Retail zFightTerrainAdjust (acclient_2013_pseudo_c.txt:1120769 = 0.00999999978,
// applied per terrain vertex inside ACRender::landPolysDraw at line 702254,
// address 006b6402). Render terrain 1 cm below its physical Z so coplanar
// building floors win the depth test. Physics path is unaffected — it reads
// the un-nudged heightmap via TerrainSurface.SampleZ.
// Closes issue #100; supersedes the hiddenTerrainCells cell-collapse hack.
vec3 terrainPos = vec3(aPos.xy, aPos.z - 0.01);
gl_Position = uProjection * uView * vec4(terrainPos, 1.0);
}