Skip to content

feat(terrain): renderoni/terrain — tiled heightfield cache and streamed LOD mesh - #40

Open
cmaycumber wants to merge 1 commit into
elemarin:mainfrom
cmaycumber:feat/terrain
Open

cmaycumber wants to merge 1 commit into
elemarin:mainfrom
cmaycumber:feat/terrain

Conversation

@cmaycumber

Copy link
Copy Markdown
Contributor

A new renderoni/terrain entry point for large procedural worlds, extracted from a shipping game.

  • TiledHeightfield: caches a caller's analytic height function in lazily filled, LRU-evicted tiles. Subclass it and override analytic (and optionally sampleExtra for extra cached channels). It provides bilinear heightAt, slopeAt with a tile-free coarse mode, prewarm, channel() and stats. Tiles are a pure function of the sampler, so an evicted tile rebuilds bit-identically, which keeps determinism.
  • TerrainMesh: streamed, chunked, distance-LOD three.js terrain over any HeightSource. It has skirts against cracks, a per-update build budget, unloading, any material, and a TerrainShading callback for per-vertex attributes (colour, texture-layer weights). Picking uses loaded chunks with an analytic raymarch fallback (floor and ceiling options for water).
  • TileCache and Buckets: exported for reuse.

This is presentation and caching only; it never writes simulation state. The game's own renderer now runs on TerrainMesh, and its chunk geometry was checked value by value against the original implementation at every LOD.

Verification: typecheck, build, 243/243 tests.

🤖 Generated with Claude Code

…ed LOD terrain mesh

TiledHeightfield caches a caller's analytic height function in lazily filled,
LRU-evicted tiles (bilinear heightAt, slopeAt with a tile-free coarse mode,
prewarm, extra cached channels). Tiles are a pure function of the sampler so
evictions rebuild bit-identically. TerrainMesh streams chunked, distance-LOD
three.js terrain with skirts, a per-update build budget, unloading, any
material, per-vertex attribute callbacks, and ray picking with an analytic
raymarch fallback. TileCache and Buckets are exported on their own.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@elemarin elemarin left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @cmaycumber. The lazy tile cache and budgeted chunk streaming are a good fit, and the tests are real. Build, typecheck and tests (243/243) pass, and dist/terrain is emitted. Before merge:

Bugs

  1. Frozen chunk matrices: matrixWorldAutoUpdate = false is applied at build time, so moving, scaling or reparenting terrain.group is silently ignored, and pick()/raymarch() disagree for a moved group. Please drop the freeze or document the limit.
  2. LOD-border normals: normals use each chunk's own step, so fine and coarse neighbours shade differently at the shared edge. The docs say borders "shade identically". Please fix the claim, or compute normals at a fixed spacing.
  3. Skirt: a fixed 6 m skirt won't hide cracks on rough terrain with the 18.75 m coarse LOD. Please scale it with the LOD spacing.
  4. Validation: cacheTiles: 0 throws a TypeError, chunkSize: 0 and lodSpacing: [0] are accepted, NaN input creates junk tiles, prewarm(…, Infinity) loops forever, and tileKey aliases beyond ±32768 tiles.

Generality
5. The defaults look tuned to Sunder March (step 9.4, 64-cell tiles, [2.5, 6.25, 18.75], [220, 520, 1150], chunkSize 187.5, raymarch constants). Please derive them from chunkSize/size, or put them in one named DEFAULTS block with units.
6. Only square, origin-centred worlds are supported. Please consider an origin/width/depth option. floor/ceiling read as water concepts; minHeight/maxHeight would be more generic.
7. Buckets (settlements and roads) isn't terrain. Please drop it from this PR.

Tests
8. Please add tests for LRU recency, negative and border coordinates, cross-LOD seams, a moved group, and add renderoni/terrain to tests/exports.test.ts.

Happy to re-review quickly.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants