perf: one lake mesh per board, and the merged board's metro layers get an LOD
Closing the merged board's red budget cells, and one of the two fixes turned out to be a win for every board in the product rather than for this one. **Every lake on a board is now one mesh.** `createWater` built a `Mesh` and a `MeshStandardMaterial` per inland-water polygon, so a board paid a draw call per lake. It went unnoticed while the boards were separate — California draws one, the Salton Sea — and a scene census on a phone found it the moment `unify.ts` folded three packs together: **water=20 against water=1**, nineteen of the fifty-eight draw calls that put the merged board over the mobile cap. They differ in nothing but shape, so the geometries merge and the material is shared. The 0.05 lift is baked in before the merge, since afterwards there is no per-lake mesh to carry it. Measured on the shipping default, unrelated to any flag: socal 218 -> 205 draw calls, bay-area 208 -> 202, california 374 -> 373, california-drive 233 -> 232. It was never free anywhere. **The metro-scale layers now follow the same reveal as the buildings.** Bridges, airports, ports and vessels are handed to `applyDetailLod` and hidden with the detail districts. That every one of them is metro detail on a merged board is measured rather than assumed: the same census showed all seven named bridges, all eight airport layers and every port mesh going from *zero* on the state pack to one on the merged board — `california.ts` authors none of them. Together they were the remaining 27 of those 58 draws, for structures sub-pixel at 1,919 m to the unit. Result on the merged board: california desktop 348,271 triangles of 440,000 and 372 draws of 415 on mobile, both green where mobile was 428 before. **`DETAIL_REACH_M` is 60 km, down from 150.** At 150 km the test asked "are you in the same half of the state as a city", which the corridor drive answers yes to along most of its length. 60 km asks "are you looking at a city", which is what the flag is for — and driving up US-101 the Southland now appears as you come into it rather than while you are still in the Salinas Valley. **The metro chapters were merged, photographed and reverted, and the reason is recorded rather than the attempt deleted.** Converting a metro rung onto this board is easy and was done correctly — `focus.lat/lng` is absolute, `distance` is horizontal in the owning board's units and `height` has already been through that board's exaggeration, so each keeps its true metres. The camera arrives exactly where it should. What is *at* that range is the problem: two scene units from the target on a 551-unit board, and the corridor there is a deliberate 4.7 km-wide atlas glyph, because DRIVE mode has to be able to drive down it on a board where a real freeway is a fifth of a pixel. The delivered frame is a black slab across San Francisco. A rung that flies you into that is worse than no rung. They come back when the corridor is drawn at true width, which is `createFreewayWorld` and the `roads` rule, not `unify.ts`. `airportsAndCard.test.ts` asserted a literal one-liner that is now two statements — the airport group is captured so the LOD can hide it. Split into the two facts it was ever about: the `?? []` call exists, and the result is added. 1,701 tests pass. The full budget passes on the shipping default. Still open on the merged board: `california-drive` mobile peaks at 315 draws against 280. The steady state is +3 drawables over the state board; the peak is the car driving into a metro and revealing it, against a cap set when the corridor had no cities on it. That is a cap to re-derive for a board that now has them, and it is an owner's call rather than a number to quietly raise — which is why this is still behind `?one=1`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+55
-11
@@ -929,6 +929,26 @@ export async function createScene(
|
||||
}
|
||||
}
|
||||
const detailReachUnits = DETAIL_REACH_M / world.metresPerUnit;
|
||||
|
||||
/**
|
||||
* The metro-scale layers, which follow the same reveal as the buildings.
|
||||
*
|
||||
* Filled after the port and vessel layers exist, a few dozen lines below;
|
||||
* `applyDetailLod` is only ever called from the frame loop, which starts
|
||||
* later still.
|
||||
*
|
||||
* **On a merged board every bridge, airport and port is metro detail**, and
|
||||
* that is a measured fact rather than an assumption: a scene census of the
|
||||
* state pack against the merged one showed all seven named bridges, all eight
|
||||
* airport layers and every port mesh going from *zero* to one — `california.ts`
|
||||
* authors none of them. Together with the crane heads, bridge lamps and hulls
|
||||
* they were 27 of the 58 draw calls that put the merged board over the mobile
|
||||
* cap, for structures that are sub-pixel at 1,919 m to the unit.
|
||||
*
|
||||
* Empty on every other board, because `hasDetail` is false there and
|
||||
* `applyDetailLod` returns before reading this.
|
||||
*/
|
||||
const detailLayers: THREE.Object3D[] = [];
|
||||
let detailShown = true;
|
||||
function applyDetailLod(): void {
|
||||
if (!hasDetail) return;
|
||||
@@ -947,18 +967,18 @@ export async function createScene(
|
||||
detailShown = want;
|
||||
blocks.count = want ? baseCount + detailLots : baseCount;
|
||||
for (const child of detailLandmarks) child.visible = want;
|
||||
for (const layer of detailLayers) layer.visible = want;
|
||||
}
|
||||
// Applied once up front so the opening frame is already correct rather than
|
||||
// correct one tick later, which is a frame the capture harness can catch.
|
||||
if (hasDetail) {
|
||||
detailShown = true;
|
||||
applyDetailLod();
|
||||
}
|
||||
scene.add(createBridges(world));
|
||||
|
||||
const bridgeGroup = createBridges(world);
|
||||
scene.add(bridgeGroup);
|
||||
// Airfields. Laid flush on the terrain rather than draped over it like a
|
||||
// road, which is why the packs no longer carry runways as `Road` records —
|
||||
// carrying both floats a dark stripe thirteen metres above every runway.
|
||||
scene.add(createAirports(world, city.airports ?? []));
|
||||
const airportGroup = createAirports(world, city.airports ?? []);
|
||||
scene.add(airportGroup);
|
||||
|
||||
/**
|
||||
* The city switching itself on after sunset. Built after `blocks` because it
|
||||
@@ -1011,6 +1031,19 @@ export async function createScene(
|
||||
scene.add(vesselLayer.group);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that every metro-scale layer exists, hand them to the detail LOD and
|
||||
* apply it once — up front, so the opening frame is already correct rather
|
||||
* than correct one tick later, which is a frame the capture harness can catch.
|
||||
*/
|
||||
if (hasDetail) {
|
||||
detailLayers.push(bridgeGroup, airportGroup);
|
||||
if (portLayer) detailLayers.push(portLayer.group);
|
||||
if (vesselLayer) detailLayers.push(vesselLayer.group);
|
||||
detailShown = true;
|
||||
applyDetailLod();
|
||||
}
|
||||
|
||||
const precipLayer: PrecipLayer | null = options.precip
|
||||
? options.precip(world, { span: boardSpan })
|
||||
: null;
|
||||
@@ -1796,12 +1829,23 @@ export const DETAIL_STANDOFF_M = 120_000;
|
||||
* How near a detail district the camera's *target* must be before that detail
|
||||
* is drawn, in true metres.
|
||||
*
|
||||
* 150 km covers a metro and its approaches from any pose that can resolve a
|
||||
* building, and excludes the middle of the state — which is what the drive
|
||||
* chapter needed. Paired with `DETAIL_STANDOFF_M`: one asks "close enough to
|
||||
* see a building", the other "looking at somewhere that has any".
|
||||
* **60 km, measured down from 150.** At 150 km the test asked "are you in the
|
||||
* same half of the state as a city", which the corridor drive answers yes to
|
||||
* along most of its length: `california-drive` revealed every building, bridge,
|
||||
* airport and port on the board while the camera was a chase view on a freeway
|
||||
* eighty kilometres from any of them, and measured 315 draw calls against a 280
|
||||
* mobile cap.
|
||||
*
|
||||
* 60 km asks "are you looking at a city", which is the question this flag is
|
||||
* actually for. A metro on this board is roughly fifty kilometres across, so a
|
||||
* target anywhere in one is comfortably inside; and driving up US-101 the
|
||||
* Southland appears as you come into it rather than while you are still in the
|
||||
* Salinas Valley — which is the better behaviour as well as the cheaper one.
|
||||
*
|
||||
* Paired with `DETAIL_STANDOFF_M`: one asks "close enough to resolve a
|
||||
* building", the other "looking at somewhere that has any".
|
||||
*/
|
||||
export const DETAIL_REACH_M = 150_000;
|
||||
export const DETAIL_REACH_M = 60_000;
|
||||
|
||||
export const ARRIVAL_STANDOFF = 1.5;
|
||||
/** How much higher, as a multiple. Larger than the stand-off: the move descends. */
|
||||
|
||||
Reference in New Issue
Block a user