Ledger #2. Built it, proved it worked, measured what it was worth, killed it.
A 10x-over-driven billow — 1.4m of flap on a 0.14m canopy — cannot move 1% of
the frame. It is not the gain, it is the geometry. Nothing ships: buildings.js
and wind.js are byte-identical to HEAD.
IT WAS BUILT, AND IT WORKED. Split the stall canopies out of the rigid awning
InstancedMesh (own mesh, own subdivided box — a 4-corner box has nothing to
ripple), gave only them a cloth billow riding R17's wind.js uniforms: sin(pi u)*
sin(pi v) pin (zero at the four posts by construction), two crossed travelling
waves, per-instance phase so forty stalls don't breathe in unison. Proven by
rendered-pixel hashes, not by eye:
cloth displaces (calm→gusty) 40f59eaf → d6d3e1f1 moves
back to calm 40f59eaf identical
uWindTime=99 at amp 0 40f59eaf identical
?classic=1, pre- vs post-build 453c0154 → 453c0154 BYTE-IDENTICAL
rest of town rides wind? (hidden) 76c8b518 → 76c8b518 still
control: cloth back frame moves again
Cost at market_square, true A/B: +0 draws (98→98) / +2,160 tris. +0, not the +1
my own comment claimed — the square's chunks hold only stalls, so the rigid list
empties and makeInstanced returns null; the cloth mesh replaces it.
AND IT IS WORTH NOTHING (amp is the same multiplier as gain):
0.02m CALM, the default weather amp 0.05% of frame
0.14m STORM, the most a player ever sees 0.21%
0.35m 2.5x over-driven 0.33%
0.70m 5x, absurd on a 0.14m slab 0.49%
1.40m 10x, flapping a body-length 0.77%
At the player's actual browsing pose, storm-force: 0.00%, max delta 1. Not one
pixel.
THE REASON IS PHYSICAL — the same physics that killed the verandah in R17. A
canopy is a horizontal sheet at y2.2 seen by a 1.7m player: edge-on or from
underneath, so vertical displacement runs almost parallel to the view ray and
makes almost no pixels. You cannot see a flat horizontal sheet flex vertically
while standing under it. No gain fixes it; 10x buys 0.77% and stops reading as
cloth.
WHAT WOULD WORK (for whoever reads this in round 35): the motion must be
perpendicular to the view — VERTICAL cloth: hanging stall skirts, a flag, a
banner, an awning valance. That is an ASSET (Lane E), not a shader. B's
applyWind/applyFabricWind seam is ready the day such a mesh exists; the shader
was never the missing piece. Ledger #2 leaves the backlog forever.
TWO VACUOUS MEASUREMENTS CAUGHT ON THE WAY. (1) `!!material.onBeforeCompile` to
prove the rigid verandah untouched — every THREE.Material inherits a prototype
no-op, so it is ALWAYS truthy; the assert could never go red. Replaced with
hasOwnProperty + a behavioural hide-and-hash control. (2) A gain sweep reporting
an identical 0.21% at gains 0.4→4.0 because I never stored the shader ref, so
uFabricGain never moved — four identical numbers across a 10x range is a sweep
that proves nothing. The constancy, not the value, gave it away. Both would have
passed as green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>