1
0

docs: the cap was never the constraint, and what the measurement says to do instead

This commit is contained in:
2026-08-24 16:45:26 -07:00
parent d6dc307d9a
commit aa3085afab
+60
View File
@@ -791,3 +791,63 @@ Two smaller things the same photographs turned up, neither of them blocking:
83,137 lots are ~1M triangles against this board's whole 400,000 cap, so the
tier is affordable only because the reach is small. Do not start it before the
exaggeration ramp, or it will be tuned against relief that is about to change.
## The cap is not what is limiting quality — the terrain is one draw call
Measured 2026-08-24 with the new `scripts/cost-at.mjs`, which costs an arbitrary
pose with `performance-budget.mjs`'s own patched GL counters. The merged board,
seeking to Lumbridge HQ and descending:
| stand-off | triangles | draws |
| --- | --- | --- |
| 400 km | 355,759 | 414 |
| 120 km | 351,019 | 327 |
| 45 km | 332,969 | 265 |
| 20 km | 332,969 | 265 |
| 7.7 km | 330,426 | 339 |
| 2.5 km | 329,392 | 334 |
**Flat, across three orders of magnitude of stand-off.** The Bay Area board at
that last pose draws **2,307,964**. So the merged board is not close to its
400,000 cap and never was: at 2.5 km over a city block it is spending 330,000
triangles, and almost none of them are the city.
`createTerrain` returns **one `THREE.Mesh` with one `BufferGeometry`** covering
the entire state. `three` frustum-culls per *object*, so a single mesh whose
bounding sphere contains California is never culled by anything, at any pose.
The same is true of the anonymous city: one `InstancedMesh`, one bounding
sphere, never culled — `updateBlocksDetail`'s repack bounds it by *authored
district distance*, which is a proxy for the frustum and not the frustum.
This reframes the whole budget question, and the reframing is the finding:
- **Raising the cap buys nothing**, because nothing is pressing against it. The
cap is a frame-time proxy and frame time is fine; the board is slow to *look
at*, not slow to draw.
- **The cost does not track the view**, which is the one property every engine
that draws millions of triangles has and this one does not. A game renders a
city at 2 km and a continent at 400 km for a similar price because the price
is set by what is on screen. Here it is set by what exists.
- So the unlock is not a bigger number. It is **making the cost a function of
the camera**, after which the near-field lot tier and a finer heightfield both
become affordable inside the cap that already exists.
Two pieces, in this order:
1. **Chunk the terrain.** A grid of meshes over the board instead of one, so
`three`'s own frustum culling has objects to reject. At 2.5 km that should
drop the terrain from ~330,000 triangles to the handful of chunks in frame.
The care is in the shadow caster: `createTerrain` packs caster-only faces
after the visible set and uses `setDrawRange(0, seen)` to hide them, so each
chunk has to keep that arrangement or the terrain stops casting. Budget the
extra draw calls — 415 of a 460 cap is what the whole-board pose already
spends, so the grid must be coarse (tens, not hundreds) or the cap moves
before the triangles do.
2. **Then chunk the detail lots spatially** rather than by district, so the same
culling applies to buildings, and only then raise `DETAIL_LOT_METRES`'s near
tier to San Francisco's 40 m. The Bay board's 83,137 lots are the proof this
is affordable *once it is culled*: that board draws 2.3M triangles at 2.5 km
and holds 60 fps, on the same GPU, with the same renderer.
**Do not do either before the relief ramp is judged**, since both are tuned
against how the ground looks and the ramp changes that. It landed at `d6dc307`.