Skip to content

Terrain hole rim drifts across LOD levels (cross-LOD gap around carved footprints) #88

Description

@krazyjakee

Summary

A terrain hole carves cleanly at LOD0 but its rim can drift by up to one cell at coarser LOD levels, opening a thin gap around the void that appears only at distance (when a coarse LOD swaps in) and vanishes up close. This is visible when a building is dropped into a footprint-sized hole: a ring gap shows around the building at distance.

Root cause

In crates/mogen-dsl/src/lower/terrain/emit.rs (build_chunk_lod_mesh), a cell is dropped from the surface only when its centre lands inside the hole footprint (hole_at(ccx, ccz)). At LOD level the sampling stride is 1 << level, so the cell centre tested is the centre of the coarse cell. Unless a wall happens to land on a grid line that is a multiple of the coarsest stride 2^(lod_levels-1), the drop boundary quantizes differently at each LOD and the rim edge shifts by up to a fine cell. The rim walls (append_wall) follow that same quantized boundary, so the gap is real geometry, not just shading.

The same applies to cap="floor" cells (append_floor) — the sealed floor extent also shifts per LOD.

Current workaround (example level)

examples/procgen/building_in_terrain.mog sidesteps this by sizing the patch so each building wall lands on a grid line that is a multiple of 4 (the coarsest stride for lod_levels=3). Verified: 0 surface triangles intrude into the footprint and rim vertices land on the walls to <=1mm at all three LODs. But this requires the author to hand-compute patch size against wall positions and pick cell counts divisible by 2^(lod_levels-1) — fragile and not possible when the footprint isn't author-controlled.

Proposed fix

Make the hole boundary LOD-invariant in the generator so any terrain + hole is gap-free regardless of patch size or hole placement. Options:

  1. Snap the drop test to the coarsest grid. Decide cell membership on the coarsest stride (2^(lod_levels-1)) for all LODs, so every level drops the same set of fine cells. The hole is then identical across LODs by construction (it grows to the coarse-grid envelope of the footprint).
  2. Carve at LOD0 and reuse that boundary. Compute the dropped-cell set once at stride 1, then for coarser LODs drop any coarse cell whose fine footprint overlaps a dropped fine cell (or is fully inside). Keeps the hole as tight as possible while staying consistent.
  3. Rim-wall skirt. Extend the existing cross-LOD skirt approach to the hole rim so any per-LOD drift is hidden by a downward skirt on the rim walls, the same way chunk edges are handled.

Option 1 is simplest and matches the existing "centre test" model; option 2 keeps holes tightest. Either removes the need for the example's manual alignment trick.

Acceptance

  • A terrain with a hole and lod_levels > 1, at an arbitrary patch size, shows no rim drift between LODs (rim vertices coincide within tolerance at every level; 0 surface triangles inside the footprint at every level).
  • Add a regression test asserting the dropped-cell boundary is identical (or skirted) across LODs for a non-aligned hole.
  • Once landed, examples/procgen/building_in_terrain.mog can drop its multiple-of-4 sizing constraint and use a natural patch size.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions