1
0

feat: give the boards a horizon, a sea that reflects, and a state worth flying over

The wide shot, which is what an anonymous visitor actually lands on.

**The sea was `MeshLambertMaterial`** — a material with no specular term at all,
by construction — on a board where water is half the frame. It is now a
low-roughness dielectric that reads `scene.environment`, with a runtime-generated
tiling swell normal map sampled twice per fragment at two scales and two
headings, so the sun breaks into a moving glitter path instead of a mirror point.
An `onBeforeCompile` patch takes the body colour toward the deep value looking
straight down and leaves it to the reflection at grazing, and walks roughness up
past 1.6 board spans so the far water cannot shimmer.

The swell spectrum is 1/k^2 and not 1/k because the first attempt was
photographed: at 1/k every component carries the same slope, the shortest wave
wins, and the sea renders as hard diagonal corduroy. A test holds it now.

**The board no longer ends in a diamond.** The sea plane went from 1.8 board
spans to 18, past the fog's far plane from anywhere the orbit reaches, and the
sky is a world-space dome rather than a screen-space gradient. That gradient was
wrong in a way dusk made obvious: the sunset band was painted along the *bottom*
of the picture, under the board, while the true horizon at the top of frame stayed
zenith blue. `daylight.ts` pinning the horizon stop to the fog colour to hide the
seam was a symptom of it.

**Terrain casts shadows.** Left off before because double-sided terrain against a
~16 m-per-texel shadow map gives acne; `shadowSide = BackSide` is the cure, shot
at four sun elevations down to +0.0 degrees to confirm no stippling. The caster is
a stride-2 decimation appended to the same index buffer and swapped in by
`onBeforeShadow`/`onAfterShadow` via `drawRange`: no extra draw call, a quarter of
the depth cost, and indistinguishable from the full-resolution caster in a
side-by-side crop. Stride 1 was measured at +65,566 triangles and would have
missed the budget by ~47,000, so it was not shipped.

**California reads as California.** It was a beige kite: the eastern edge one
ruled line for five degrees of latitude, the south closing in a diagonal V, the
whole south-east a featureless tan wedge. Now the coast runs to the Mexican
border with San Diego on it, the eastern edge follows the Colorado and the Nevada
diagonal, and the south-east is the Basin and Range — forty parallel desert ridges
throwing shadows east, Death Valley as a white pan between the Panamints and the
Black Mountains, the Salton Sea the one cool value for two hundred kilometres.
The opening pose is retuned to the bigger board; the old 452/392 stand-off left a
slab of empty ocean where the state should be.

**The aircraft were six pixels.** Measured, by enlarging a screenshot 200% to
find one at all — indistinguishable from a dead pixel, on a board whose entire
claim is that the sky is live. They are airliners now, with planform and trail,
and clicking one raises its card for a signed-out visitor.

**The Model X is off the wall.** It stood at floor level outside a studio 188 m up
a Transbay tower, reading as a car balanced on a parapet. The apron is now chosen
from `site.elevation`, which the pack already carries — not from an office id,
which is the bug class this repo already hit once when a door marker gated on
`id === "sf"` and would have pinned the Los Angeles building to San Francisco.

Also fixed, and nearly shipped: sea z-fighting dithered every flat piece of ground
on the Bay Area and SoCal boards. And one test asserted an exact source line for
the water material, so the better multi-line implementation failed it — it now
asserts the property (dielectric, metalness 0, low roughness) rather than the
author's first guess at formatting.

Tests 964 -> 1015. California desktop 562/650 draw calls and 728,744/750,000
triangles — 2.8% of triangle headroom left, which is the number the next person
should check first. No budget was raised.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-21 23:43:14 -07:00
parent 655848746d
commit 8fb85cd2e5
30 changed files with 4781 additions and 257 deletions
+40 -7
View File
@@ -50,6 +50,7 @@ const LUMBRIDGE_HQ = (await import("../../offices/lumbridge-hq.ts")).default;
const MATEO_COURT = (await import("../../offices/mateo-court.ts")).default;
const { initialDeviceState } = await import("../../devices/types.ts");
const { createSimulatedVehicleTelemetry } = await import("../../transport/vehicleTelemetry.ts");
const { arrivalGroundFor } = await import("../../transport/exteriorVehicle.ts");
type Office = typeof LUMBRIDGE_HQ;
@@ -277,7 +278,7 @@ test("a device reading reaches the indicator on the hardware", () => {
// ---- The exterior ----------------------------------------------------------
for (const [id, pack] of PACKS) {
test(`${id}: a Model X is parked on the pack's arrival stall`, () => {
test(`${id}: the exterior matches the ground its site actually has`, () => {
const arrival = pack.site?.arrival;
assert.ok(arrival, `${id} authors no arrival anchor`);
const { scene, rig } = build(pack);
@@ -291,8 +292,19 @@ for (const [id, pack] of PACKS) {
exterior.traverse((object) => {
if (object.userData.vehicleModel === "model-x") car = object;
});
assert.ok(car !== null, "the apron was built without a car on it");
// An apron is ground, and `lumbridge-hq`'s studio floor is 188 m above the
// pavement outside it. Built literally at the stall's own storey it is a
// paved pad and a car in open sky beside the west wall, which is what this
// shipped for one build. Read off the site rather than the id, because
// reading off the site is exactly what the layer under test must do.
if (arrivalGroundFor(pack.site?.elevation ?? 0) === "air") {
assert.equal(car, null, `${id} parked a car in the air`);
assert.equal(exterior.children.length, 0, "an off-ground site draws nothing");
return;
}
assert.ok(car !== null, "the apron was built without a car on it");
const at = (car as THREE.Object3D).getWorldPosition(new THREE.Vector3());
const floorY = scene.plan.level(arrival.levelId)?.floorY ?? 0;
assert.ok(
@@ -302,8 +314,8 @@ for (const [id, pack] of PACKS) {
);
assert.ok(
Math.abs(at.y - floorY) <= 1.5,
`the apron must stand on the floor of ${arrival.levelId} (${floorY} m), not at the ` +
`plan origin — a podium deck is the whole reason the stall names a storey`,
`the apron must stand on the floor of ${arrival.levelId} (${floorY} m), not at ` +
`the plan origin — the stall names a storey for a reason`,
);
} finally {
scene.dispose();
@@ -557,10 +569,31 @@ test("the water reflects rather than absorbing, now that there is a sky to refle
"Lambert has no specular term at all, which is why half the California board " +
"rendered as one flat blue value at every hour and from every angle",
);
// Assert the PROPERTY, not the formatting. The first draft of this test
// matched one exact source line — `MeshStandardMaterial({ color: pal.sea,
// roughness: 0.14, metalness: 0 })` — and the sea that shipped is a
// multi-line construction at roughness 0.2 with an `onBeforeCompile` patch
// that flattens it toward the horizon. The implementation was better than the
// literal and the test failed anyway, which is the failure mode of asserting
// on source text: it pins the author's first guess rather than the behaviour.
const build = water.slice(0, water.indexOf("\n}"));
assert.match(
build,
/MeshStandardMaterial\(/,
"the sea must be a dielectric that reads `scene.environment`",
);
const roughness = Number(/roughness:\s*([\d.]+)/.exec(build)?.[1]);
assert.ok(
/MeshStandardMaterial\(\{ color: pal\.sea, roughness: 0\.14, metalness: 0 \}\)/.test(source),
"the sea must be a low-roughness dielectric, so it takes both the sun's glint " +
"and `scene.environment`",
Number.isFinite(roughness) && roughness > 0 && roughness <= 0.35,
`the sea's roughness is ${roughness}; it must be low enough to return a sun ` +
`glint and a sky reflection, and above zero so it is water and not a mirror`,
);
assert.match(
build,
/metalness:\s*0\b/,
"water is a dielectric: metalness 0 is what makes the reflection white " +
"rather than tinted by the sea colour",
);
});