feat(client): watertight cliff rendering - edge smoothing + continuous relief darkening #264

Merged
panda merged 6 commits from feat/cliff-stepped-ground into main 2026-08-02 22:46:47 +02:00
Collaborator

Summary

Reworks how cliffs render so terrain elevation reads cleanly, fixing the artifacts the earlier
per-quad "steep-bank" attempt (①b, #262) introduced. Three problems fixed:

  • Black T-junction cracks at cliffs — ①b emitted the ground per-quad with NO shared vertices, so a
    cliff quad's flat lip didn't meet its plain/corner neighbours; the deferred composite discarded those
    uncovered slivers to the black backbuffer. Fixed by recovering the watertight shared-vertex ground
    mesh
    (#249): no holes → no black, ever.
  • Elevation invisible — the recovered mesh alone reads flat. Cliffs now darken continuously in
    the shader from the relief field's true-cliff channel (r.a, which is 0 for walkable ≤step tiles), so a
    sheer face reads as a dark upright band on ANY orientation — no discrete wall geometry, no diagonal
    "picket-fence".
  • Diamond / "right-angle" teeth on cliff outlines — the recovered #247 display-Z edge smoothing
    rounds a cliff's grid-aligned jagged outline into a ramp, fed to BOTH the mesh (geometric teeth) and the
    relief field (shading teeth), so both come out smooth. Limited to cliff edges (walkable terraces stay
    crisp); Sigma tuned to 1.4 on the visual gate.

Net effect supersedes the ①b banks on this branch (CliffBankTessellation removed). Client-render only
— no wire/protocol/server change, so ProtocolVersion is untouched.

Screenshots / recording

Captured by piloting the client via the debug harness (docs/debug-harness.md), fresh DB, admin
test, on the authored asterra mountain. Per spot: login test → key Enter / type /tp <x> <y> /
key Enter → screenshot. No black cracks, cliffs legible as dark bands, no diamond teeth:

mountain_cliff_6599_2848

mountain_cliff_6599_2848.png

z100_cliff_foot_6419_2804

z100_cliff_foot_6419_2804.png

dirt_grass_border_5115_4786

dirt_grass_border_5115_4786.png

How it was tested

  • dotnet build (whole solution): 0 warnings.
  • dotnet test: all green (10 projects; per-quad bank geometry + its tests removed, TerrainDisplayHeight
    golden tests restored).
  • dotnet csharpier check: clean.
  • Visual gate (above): harness screenshots at the mountain cliffs and a biome border on a fresh DB.
    Shader recompiled via MGCB; ground_blend.xnb committed.

Invariants Check (from the design review, #262)

  • Scope ✓ — fixes the agreed cliff-rendering task, no new system.
  • Server-authoritative ✓ — display-only; derives from authored map Z; walkability/sight still read terrain flags.
  • Protocol versioned ✓ (no bump) — the darkening/smoothing is client-internal; nothing crosses the wire.
  • Screen HARD GATE ✓ — logic stays in GroundBlendRenderer + Client.Core; no Screen touched.
  • Client engine-independence ✓ — TerrainDisplayHeight (smoothing) is pure Client.Core, unit-tested; only vertex upload + the .fx live in Client.
  • Assets ✓ — cliffs sample the biome's real land/<art>; no PlaceholderArt.
  • Multi-platform ✓ — SM3 HLSL on the existing DesktopGL path; no OS-specific API.
  • (Persistence / GM / Spells / AoI / options / typed-content) N/A — no such surface touched.

Checklist

  • just lint passes (CSharpier + analyzers, zero warnings)
  • just test is green
  • The whole solution builds (client and tools included)
  • Multi-platform preserved (server on Win/macOS/Linux, client on Win/macOS)
  • Tests added/updated for this change
  • Linked the related issue (#262) and its Definition of Done is met
## Summary Reworks how cliffs render so terrain elevation reads cleanly, fixing the artifacts the earlier per-quad "steep-bank" attempt (①b, #262) introduced. Three problems fixed: - **Black T-junction cracks** at cliffs — ①b emitted the ground per-quad with NO shared vertices, so a cliff quad's flat lip didn't meet its plain/corner neighbours; the deferred composite discarded those uncovered slivers to the black backbuffer. Fixed by recovering the **watertight shared-vertex ground mesh** (#249): no holes → no black, ever. - **Elevation invisible** — the recovered mesh alone reads flat. Cliffs now darken **continuously** in the shader from the relief field's true-cliff channel (`r.a`, which is 0 for walkable ≤step tiles), so a sheer face reads as a dark upright band on ANY orientation — no discrete wall geometry, no diagonal "picket-fence". - **Diamond / "right-angle" teeth** on cliff outlines — the recovered #247 display-Z **edge smoothing** rounds a cliff's grid-aligned jagged outline into a ramp, fed to BOTH the mesh (geometric teeth) and the relief field (shading teeth), so both come out smooth. Limited to cliff edges (walkable terraces stay crisp); `Sigma` tuned to 1.4 on the visual gate. Net effect supersedes the ①b banks on this branch (CliffBankTessellation removed). **Client-render only** — no wire/protocol/server change, so `ProtocolVersion` is untouched. ## Screenshots / recording Captured by piloting the client via the debug harness (`docs/debug-harness.md`), **fresh DB**, admin `test`, on the authored `asterra` mountain. Per spot: `login test` → `key Enter` / `type /tp <x> <y>` / `key Enter` → `screenshot`. No black cracks, cliffs legible as dark bands, no diamond teeth: **mountain_cliff_6599_2848** ![mountain_cliff_6599_2848.png](https://git.homelab.devncode.it/attachments/88349ffb-1605-463d-a57d-11e921654111) **z100_cliff_foot_6419_2804** ![z100_cliff_foot_6419_2804.png](https://git.homelab.devncode.it/attachments/77d03ac5-62a6-41d1-a57f-db4726de4d52) **dirt_grass_border_5115_4786** ![dirt_grass_border_5115_4786.png](https://git.homelab.devncode.it/attachments/06e4b460-6b08-4aa5-ad98-0f28a0fdff2a) ## How it was tested - `dotnet build` (whole solution): **0 warnings**. - `dotnet test`: **all green** (10 projects; per-quad bank geometry + its tests removed, `TerrainDisplayHeight` golden tests restored). - `dotnet csharpier check`: clean. - **Visual gate** (above): harness screenshots at the mountain cliffs and a biome border on a fresh DB. Shader recompiled via MGCB; `ground_blend.xnb` committed. ## Invariants Check (from the design review, #262) - Scope ✓ — fixes the agreed cliff-rendering task, no new system. - Server-authoritative ✓ — display-only; derives from authored map Z; walkability/sight still read terrain flags. - Protocol versioned ✓ (no bump) — the darkening/smoothing is client-internal; nothing crosses the wire. - Screen HARD GATE ✓ — logic stays in `GroundBlendRenderer` + `Client.Core`; no Screen touched. - Client engine-independence ✓ — `TerrainDisplayHeight` (smoothing) is pure `Client.Core`, unit-tested; only vertex upload + the `.fx` live in `Client`. - Assets ✓ — cliffs sample the biome's real `land/<art>`; no PlaceholderArt. - Multi-platform ✓ — SM3 HLSL on the existing DesktopGL path; no OS-specific API. - (Persistence / GM / Spells / AoI / options / typed-content) N/A — no such surface touched. ## Checklist - [x] `just lint` passes (CSharpier + analyzers, zero warnings) - [x] `just test` is green - [x] The whole solution builds (client and tools included) - [x] Multi-platform preserved (server on Win/macOS/Linux, client on Win/macOS) - [x] Tests added/updated for this change - [x] Linked the related issue (#262) and its Definition of Done is met
panda merged commit 933fea3d6b into main 2026-08-02 22:46:47 +02:00
panda deleted branch feat/cliff-stepped-ground 2026-08-02 22:46:47 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
marco/IsoMmo!264
No description provided.