flowers.html: the flowers, given a Three.js stage of their own - #42
Conversation
… a new stage flowers.html is built by flowers/build.js the way canalisation.html is built by build.js: one file, no server, no CDN, parsed before written. Three r147 UMD is vendored. The engine comes in whole minus 60_render and 80_main — the two files this piece replaces. It adds no geometry code: flDrawSpecimen is the shipped organ loop calling the shipped emitters, minus the occlusion cull and the microscope, plus one thing the shipped buffers never had — beginOrgan/endOrgan bracketing, so every mesh knows which organ it belongs to and what its q was. Veins are captured as the Blender bridge captures them (a, b, w0, w1, colour, emis — side dropped) and camera-faced per frame in the vertex shader, which is ROADMAP 11's twelve-float ribbon. The shading is 60_render.js transliterated, not reinterpreted: hemisphere ambient, key at 0.9, back-transmission at 0.55, rim at 0.7, emissive x3, fog from the subject's near face, veins as colour TIMES emissive blended (SRC_ALPHA, ONE) with depth writes off, ACES -> vignette -> grain -> gamma. Two boots were spent learning that the palettes do not survive an improvised renderer: the first guess lit the plant as a silhouette, and opaque vein ribbons drew the reticulum as dirt. Co-Authored-By: Claude Fable 5 <[email protected]>
…ut had no room for flPetalSurface is blade()'s surface half emitting pos/nrm/col/emis exactly as shipped — same veinTint, same 0.24 glow, same senescence lag, same fenestration cut — plus dd (distance-to-vein), q (floral identity), u, v per vertex. With a shader that ignores the extra floats it is pixel-identical to the shipped lamina, which is the point: parity first, mechanisms on top. Floral organs now route their surface through it; their veins still ride the shipped path. Co-Authored-By: Claude Fable 5 <[email protected]>
?focus=flower now measures the union bound of what the capture actually put in the petal stream (plus the fruit's triangles) for the chosen axis. Two hand-derived framings shipped screenshots taken from inside the corolla first — a petal rides a petiole and is as wide as it is long, so nothing short of the geometry knows where a flower ends. Same lesson as the shipped page's petal-reach fix, one level stronger. Co-Authored-By: Claude Fable 5 <[email protected]>
…nisms, not poses 12_form.js replaces the shipped flat-card petal (curl = -bl*0.05) with two published results evaluated in closed form each frame: - Liang & Mahadevan 2011 [D]: a petal is a curved shell, and anthesis is a bifurcation. Edge growth strain loads the shell; past beta* the longitudinal curvature unbends while the lateral curvature curls, so a bud is a cup and a bloom is a recurved, laterally rolled petal BECAUSE THE EQUATION SAYS SO. Driving the load with the organ's own dev is the one [OURS] coupling; the identity lag (high q stays nearer the bud state) gives SCIENCE.md's unbuilt 'enclosing growth at high q' a mechanism. - Cerda & Mahadevan 2003 [D], experimentally verified: edge ripple wavelength and amplitude from sheet thickness and edge strain, evaluated with a 150 um petal at the world's own 0.0625 m/unit and the lily's measured strain profile. The ripple is drawn at the millimetres the formula returns. The veins are mapped through the SAME displacement (flPetalVeins mirrors the shipped bladeVeins in its PXR=0 form) — a vein floating off a curved petal was the first thing the naive version produced. The petal shader gains four published mechanisms, each reading a computed channel: back-transmission boosted where tissue is far from a vein (van der Kooi 2016 [D]: transmittance exceeds reflectance; dd as thinness is [OURS]), with col^2 double-pass pigment filtering; a velvet ring-NDF whose tilt matures 22->52 deg with dev (Ren 2017 [D]); saturation deepening at constant pigment (Gorton & Vogelmann 1996, Noda 1994 [D] — the cone steers light INTO the pigment); and a proximal bullseye as a pow() pigment zone thresholded on u, drawn per specimen from Todesco 2022's trimodal distribution [D]. flowers/parity.test.mjs is the gate: 20 checks reconciling the captured streams against the shipped drawSpecimen float for float, including exact ribbon-count parity for the mirrored vein pass. Co-Authored-By: Claude Fable 5 <[email protected]>
17_spots.js runs Ding, Yuan et al. 2020's modified Gierer-Meinhardt system — their complete published parameter set, verbatim — on the petal's own lamina lattice rather than their 100x100 square. Zero-flux boundaries fall out of the cut lattice for free, the arrangement inherits the real tissue geometry seed by seed, and no two specimens spot alike. Baked once per library petal (~50ms, same category as cellTable), shipped to a 3-row atlas, and read by the petal shader as a pigment-exponent multiplier strongest in the guide zone (Mimulus spots live in the throat). Two numerical departures from the paper are flagged in the file header. First render charred the petals — the three pigment exponents stack multiplicatively — so the zone/spot/maturity gains were rebalanced measured against the same frame. Co-Authored-By: Claude Fable 5 <[email protected]>
flowers/README.md: what the piece is, which mechanism each pixel comes from, the [D]/[OURS] provenance of every constant, and what was deliberately not built (the blue halo, nyctinasty, lattice relaxation) with the reason each time. Co-Authored-By: Claude Fable 5 <[email protected]>
…wired A double flower is a C-class failure (AGAMOUS loses the WUS shutoff; Lohmann 2001, Lenhard 2001) and the engine already had the mechanism: floral organ identity IS the apex consuming itself. Four factors name what was hardwired, so a specimen can lose determinacy without any shipped species moving: - apexRenew (0): fraction of each recruited patch the stem-cell pool replaces in consumeApex(). At 0 the line is exactly the old one. - floralElong (0.22): the floral tip-elongation tax, previously a literal 0.22 at the elongation site. - floralStretch (1): the same tax for the subapical stretch, which was never applied to floral axes — that asymmetry is the shipped look and 1 preserves it exactly. - floralNode (0.10): the floral minInternode factor, previously a literal 0.10. Measured on Ember Creeper seed 21: renewal 0.6-0.8 takes a flower from 6 petals to 14-23; compression takes a 22-petal raceme spread over 8.4-13.0 units of axis to a 0.26-0.40-unit corolla. All three moves have to land together with floralGrace raised, or the founding gate and the grace each silently un-double the flower back to 9 petals — both failure modes measured, both are the stalled-shoot trap. smoke: 73/73 before and after. The eight herbs and the conifer are unchanged organ for organ (every default is the old literal). Co-Authored-By: Claude Fable 5 <[email protected]>
…r doubles AJ's verdict on the first cut: "weird flashy things that look glitchy near the petals", and the diagnosis ran four layers deep, each measured by isolating a stream or a term in the live page: - Inner organs were fed through the petal shell physics, whose curvature scales as 1/L: a 0.4-unit stamen-analog rolled into a crumpled tube whose flipping normals strobed the sheen. Petals only now; inner organs take the shipped card. - The Cerda-Mahadevan ripple (lam ~0.11) landed 2-3 mesh samples per wavelength and aliased into jagged offsets. flPetalForm now fades the amplitude below ~4 samples/wavelength — the vein-LOD law applied to a ripple — and floral organs draw at the lattice's own resolution. - The pigment stack (bullseye 0.8 in a hard ring, spots 0.9 full-face, dev 1.25) turned a smooth pale bake into sharp maroon blotches. Isolating raw albedo showed the bake was beautiful on its own; the stack now works at a whisper in a wide soft zone. - A one-sided lambert threw half of every cupped petal into hard shadow, which read as meat. Thin tissue is lit from both sides now: wrapped diffuse, wide transmission lobe — van der Kooi's actual point, applied to the shading and not just a boost term. The post chain is 60_render.js whole now — bright + three widening blurs for bloom, the scene blurred at half res for defocus, alpha carrying linear depth, COMP_FS verbatim — replacing UnrealBloomPass (vendor 53kb lighter) and adding the one lens effect a flower close-up is made of. The additive passes keep dest alpha via the Three spelling of blendFuncSeparate(SRC_ALPHA, ONE, ZERO, ONE). Focus racks on the shipped director's law. ?form=double is the C-class mutant on the four new engine knobs plus floralGrace 960: 20-23 petals per flower in a 0.26-0.40-unit corolla, inner whorls lagging open behind the outer ones because bloom lag rides q. ?homeo= and ?renew= move the thresholds. Also: pollen in the one air (18_pollen.js — Stokes settling at 3.3cm/s inside the published 2-4, grains ride windAt with fade envelopes), and bestFlower's truthiness test silently dropped axis 0 — the terminal flower — to the wide shot. parity: 20/20 throughout. Co-Authored-By: Claude Fable 5 <[email protected]>
…n colour petalGrade (default 0, the old line exactly) scales a petal down with its identity q — a homeotically converted stamen is a petaloid stamen, smaller than a true petal — so the doubled corolla grades outer-large to inner-small. Floral petioles wear the petal's base colour instead of stem brown: a 20-petal corolla drew its stalks as a wire armature. ?form=double is the default now (?form=wild is the shipped configuration, untouched); the hint and README carry the whole story, including the three measured traps that each silently un-double the flower, and the one known gap (flower focus has no sight-line cull, and a Cathedral Fern shoots through its own canopy). Emergent and nobody designed it: the Nightglass Parasol's compressed corolla ends up wrapped around its terminal fruit — a glowing moon in a ring of fenestrated petals. smoke 73/73, parity 20/20. Co-Authored-By: Claude Fable 5 <[email protected]>
|
Round 2, from AJ's look: "more magnificent, and the flashy things near the petals are glitchy." Three commits. The numbers-as-review-currency version: The glitch ran four layers deep, each isolated in the live shader before fixing — inner organs fed through shell physics whose curvature scales 1/L (a 0.4-unit stamen-analog rolls into a crumpled tube; petals only now); the Cerda–Mahadevan ripple landing 2–3 mesh samples per wavelength and aliasing (Nyquist fade in flPetalForm — the vein-LOD law applied to a ripple); the pigment stack at full strength turning a smooth pale bake into maroon blotches (raw-albedo isolation showed the bake was beautiful alone; the stack whispers now); and a one-sided lambert reading as meat on cupped petals (thin tissue is lit from both sides now — van der Kooi applied to the model, not bolted on). The post chain is 60_render.js whole now — bright + 3 widening blurs, half-res defocus with depth-in-alpha, COMP_FS verbatim. UnrealBloomPass is gone (vendor 53 kb lighter) and the piece finally has the shipped depth of field, racking on the shipped director's focus law. The structure ask became the C-class mutant. Four engine knobs, every default the literal that was hardwired (smoke 73/73, herbs bit-identical):
Record shots in Also fixed: 🤖 Generated with Claude Code |
The engine's floral identity coordinate q was collapsed to one binary
(petal / not-petal). `whorlBands` bands it outermost-to-innermost into
sepal / petal / stamen / carpel — sharp boundaries, AP3/AG mutual
antagonism — and every part of a real flower falls out: sepals ARE
leaves (the non-petal leaf request already hands one out), stamens are
anthers on filaments (org.stalkX, read by petioleOf, so the physics
sees the same stalk the renderer draws), the carpel is a pale style at
the crown. `floralDome` caps the converted dome at a characteristic
size in founder-patch radii — without it a terminal apex founds ten
organs at q ~= 0 and reads as one whorl (measured; the working
axillaries convert at exactly 3.0 organR). All defaults preserve the
shipped species bit for bit: smoke 73/73, parity 20/20.
flowers.html: form=abc is the new default, two floral programs assigned
per species from a measured 8-species sweep; nectar guides in the petal
shader (Venosa: pigment over the vasculature, off the dd channel the
engine already computes); the flower shot now steers to the flower's
own facing, prefers subjects clear of the trunk, and ports the shipped
sight-line occlusion cull (extended one organ-length past the subject —
a face-on shot sits INSIDE the canopy, which the shipped director never
did). Record shots: flowers_{ember,fern,parasol}_abc.png
Co-Authored-By: Claude Fable 5 <[email protected]>
CYC/DICH dorsoventral asymmetry as sp.zygomorphy (default 0, shipped bit-identical): the adaxial reference is the horizontal negation of the axis's own first segment — the direction the bud grew out of its parent — so nothing is stated, and a terminal flower has no reference and stays radial, which is real peloria. Dorsal petals enlarge and stand, ventral petals reflex, a strongly dorsal stamen aborts to a staminode (Luo 1996/1999). ?zygo=0.85 in flowers.html, off by default. README carries the whole round; record shot flowers_ember_zygo.png. Co-Authored-By: Claude Fable 5 <[email protected]>
Round 3 — the flower is four organs nowAJ asked for significantly more complex structure. The answer was already in the engine: floral identity The full ABC model is the default form ( Engine knobs added (40_plant.js / 39_fall.js), every default the shipped literal — smoke 73/73, parity 20/20, herbs bit-identical:
Two floral programs assigned per species from a measured 8-species sweep — Cathedral Fern is S8 P1 A0 C1 under program A and S3 P5 A4 C1 under B (smaller dome, more renewal, bands shifted to its measured q clusters). Spiral Ossuary founds 3 floral organs even wild; its flowers were always inconspicuous and stay that way honestly. Nectar guides: The flower shot is a photographer now: it eases to the flower's own facing blended away from the trunk, scores down corollas pressed against the trunk (one was framed with the trunk through its face — 0.36 units off a 2.13-radius corolla), and ports the shipped sight-line cull (the round-2 known gap) with one extension the shipped director never needed: the window reaches one organ-length past the subject, because face-on sits inside the canopy. The cull is view-dependent, so capture re-runs on camera motion — at Record shots in Fastest look: 🤖 Generated with Claude Code |
…new where each one goes receptacle (default 0, shipped exact): un-collapse the floral dome. q RECORDS the founding radius; placing every floret on the axis line discarded it. Under the knob a floret is offset by receptacle*(1-q) — rim founded first, centre last — and rides the TIP, so the receptacle never elongates (that is what makes a head, not a spike; measured 2.9 -> 0.0 axial span) while floral elongation below it becomes the peduncle: the daisy bolts, 9-10 unit scapes. ?form=daisy maps the SAME four whorl bands onto Asteraceae anatomy: sepal = phyllary, petal = ray, stamen = disc floret (which is why the disc glows and sheds pollen), carpel = centre. 52-53 florets per axillary head measured. tropism .002 holds a head ~3 units clear of the trunk (at .02 a 12-unit peduncle climbs to 0.4 clear). Facing steer reads the tip tangent, and the away-from-trunk blend tapers with measured clearance. smoke 73/73, parity 20/20. Co-Authored-By: Claude Fable 5 <[email protected]>
The daisy's centre would not fill, and the reason was five plant-steps deep: every fruit on the specimen was BARREN. Control first (venation.mjs's lesson): wild Ember seed 21, no overrides, is barren too — in flowers.html AND in the shipped app, deterministically, since makeSpecimen first drew fruit chemistry from the seed. Isolated to the draw: ovule patterning on the 642-cell shell fails outright when T/D < ~5.3 (sharp: 12-20 ovules one side of the boundary, zero the other; mapped on a 6x5 T-D grid, 6 fruit seeds per cell). The shipped ranges T[14,34] x D[1.8,4.2] include that corner and 5 of 40 specimen seeds land in it — sterile for life, 'ripe' never reached, a seed head with nothing in it. One clamp after the draws: D <= T/6 (~15% margin over the cliff). Fertile specimens bit-identical — their draws pass through — and the PRNG call order is untouched. Every daisy head now ripens a 14-16-ovule fruit at the disc's centre, measured to step 9500. smoke 73/73, parity 20/20. Co-Authored-By: Claude Fable 5 <[email protected]>
Round 4: the capitulum — a daisy is a hundred flowers
Two engine additions (both default-0, shipped bit-for-bit; smoke 73/73, parity 20/20)
The sterile corner (a shipped bug older than this piece, fixed here)The daisy's centre would not fill, and the diagnosis ran five layers deep: every fruit on the specimen was barren. Control first — wild Ember seed 21, zero overrides, is barren too, in flowers.html and the shipped app, deterministically. Isolated to Also in this round: the flower shot reads the tip tangent rather than the base-to-tip chord (a bolting scape curves), and the away-from-trunk blend tapers with the subject's own measured clearance — a head already held out keeps its facing. The fastest lookRecord shots in the worktree: 🤖 Generated with Claude Code |
…gated ?form=columbine, entirely flowers-side. Two mechanisms: sepalPetaloid routes whorl 1 through the petal stream (B-class expanded OUTWARD — the double's lever pointed the other way), and wb.spur maps the petal's proximal sheet domain through a roll (flat sheet as its w=0 limit) and carries it backward by Puzey et al. 2012's [D] result that spur length is achieved solely through cell-shape anisotropy. Slenderness is the same anisotropy (1/sqrt(a), between the paper's two conservation limits; 1 measured as a sausage, 1/a as a wire). The veins wrap in with the sheet, so every spur has its own vasculature ending at a softly lit nectary. Spur angle pi+petalTilt maps all petals' tubes anti-parallel to the flower axis: a parallel descending ring. A small receptacle reuses round 4's mechanics as the PEDICEL (trunk clearance 0.24 -> 1.25) and the photographer shoots spurred flowers in three-quarter, because face-on a columbine reads as a mallow (measured). Parity 20/20, smoke 73/73 (no engine edits). Co-Authored-By: Claude Fable 5 <[email protected]>
|
Round 5: the columbine — `?form=columbine`. AJ asked whether we could reach Aquilegia-level complexity; the answer decomposed onto the existing machinery plus one genuinely new mechanism, and the new one comes with hard numbers. The nectar spur (`flowers/12_form.js` + `15_petal.js`). Puzey, Gerbode, Hodges, Kramer & Mahadevan (Proc. R. Soc. B 279:1640, 2012 `[D]`) — the same Mahadevan as the pitchfork bloom and the edge ripples, so the whole corolla now runs on one lab's physics — showed spur-length diversity across the whole genus is achieved solely through cell-shape anisotropy. Built as a domain map with the flat sheet as its limit:
Petaloid sepals (`20_draw.js`): `sepalPetaloid` is the double's homeotic lever pointed the other way — B-class into whorl 1. Sepals go through the petal stream wearing the species' full petal colour while true blades pale toward cream (held at 0.35/0.48: past ~0.5 the transmission lobe `alb²·1.5` exceeds 1 and the blades blow white through the bloom chain). The program (measured, col_probe): renew .70 + dome 3 + cap 32 founds S7 P8 A5-9 per flower — the q-zero founding pile IS the sepal whorl. A small `receptacle` (0.25) reuses round 4's mechanics as the pedicel: trunk clearance went 0.24 → 1.25 and the director can finally photograph an axillary. And the photographer learned that a spurred flower is shot in three-quarter — face-on, a columbine reads as a mallow (measured). Zero engine edits this round: parity 20/20, smoke 73/73 untouched. Fastest look: 🤖 Generated with Claude Code |
What this is
A second single-file piece,
flowers.html, built byflowers/build.jsexactly the waycanalisation.htmlis built — one file, no server, no CDN (Three r147 UMD is vendored invendor/), parsed before written, duplicate-scan gated. It grows a real specimen with the shippedmakeSpecimenand points everything at the flower, which on the shipped page is a minor character wearing the foliage code.It adds no growth code and no organ geometry.
flDrawSpecimenis the shipped organ loop (minus occlusion cull and microscope) calling the shipped emitters; aBufferssubclass records per-organ[start,end)ranges per stream — organ identity the shipped buffers never carried — and captures veins the way the Blender bridge does (a, b, w0, w1, colour, emis,sidedropped), expanded camera-facing per frame in the vertex shader. That is ROADMAP 11's "a ribbon as twelve floats", incidentally working.The numbers (review currency)
flowers/parity.test.mjs: 20 checks, 0 failures across Ember Creeper + Nightglass Parasol @ 1400 steps — captured streams reconcile with shippeddrawSpecimenfloat for float (tri: shipped 152220 == captured 139500 + petal 12720; exact ribbon-count parity 8608 == 8608 for the mirrored vein pass), organ ranges monotone and covering, petalqrecorded on every petal.node build.js && node test/smoke.mjs: 73 checks pass,canalisation.htmlbyte-identical (this PR touches nothing insrc/).The shading is transliterated, not improvised
First boot lit the plant with a guessed lighting model and got a silhouette — the palettes only mean what
60_render.jsmakes them mean. The scene now carries that pipeline line for line: hemisphere ambient, key at 0.9, back-transmission at 0.55, rim at 0.7, emissive x3, fog measured from the subject's near face, veins additive at colour x emissive with depth writes off, ACES → vignette → grain → gamma. ("Match the shipped look first" — it is now literal.)The petal mechanisms, each from a published result, each reading a computed channel
The shipped petal is a flat card with a 5% droop, coloured by a gradient. The petal stream (16 floats/vertex) carries
dd(distance-to-vein),q(floral identity — computed since the whorl work, never drawn),u,v,dev,lib:beta*unbends the longitudinal curvature and rolls the lateral one. A bud is a cup and a bloom is a recurved petal because the equation says so — no animation curve. Driving the load with the organ's owndevis the one [OURS] coupling; highqlagging the bloom gives SCIENCE.md's unbuilt "enclosing growth at high q" a mechanism.ddas thinness is [OURS]), squared-albedo transmission tint.uper specimen, drawn from the published trimodal distribution.cellTablecategory).Not built, deliberately: the diffraction blue halo (RGB can only fake it), nyctinasty (needs a temperature cycle — a genuinely new global, ROADMAP 0z1's argument, left for a session that wants it).
flowers/README.mdcarries the full provenance table including every stated constant.Try it
?species= ?seed= ?speed= ?ff= ?focus=flower ?hold=none. A local shot is atshots/flowers_ember_portrait.pngafter a capture run.Process notes
Two Opus 5 subagents did the groundwork: an engine map (which found
qthrown away on petals,ddcomputed and used only as a tint, andpedicelwritten-never-read) and a petal-morphogenesis literature sweep with [D]/[I]/[OURS]/⚠ flags whose implementation shortlist is what the mechanism layer follows. Framing bugs were fixed by measuring (flower framed from its drawn bounds after two hand-derived versions put the camera inside the corolla).🤖 Generated with Claude Code