Stolen from the shader half of Sebastian Lague's graphics-library video (the Voronoi farm-plot trick), because it turns out to be an anatomy tool rather than a decoration: mucosa at SEM scale IS a Voronoi diagram. Lane D's own oral prompt asks FLUX for a "cobblestone pavement of flat polygonal squamous epithelial cells" — that is a Voronoi described in English, and generating it in the fragment shader instead is free, never repeats, and can do the one thing a baked texture never will: BREATHE. Membrane width rides vPulse, the same wave the vertex shader displaces with, so the pavement compresses exactly where the muscle contracts. - F2-F1 Voronoi (9-tap), multiplied into the detail LUMINANCE, never added — D's texture stays the author of the look and this is structure underneath it. Applied to both the textured and the assets-optional fallback path. - Rides D's own tiling (duv * scale), so cells hold their physical size on a radius-7 hiatus and a radius-70 sea — the upstream arc-length fix does that work for free. - Compiled out with a define, not branched out on a uniform: a biome that wants no pavement pays nothing for nine hashes a pixel. Per-biome, because a pavement is a CLAIM ABOUT TISSUE and not a filter: oral 0.50 (squamous epithelium is the strongest case in the body), appendix 0.48 and colon 0.42 (biofilm mats are literally cells), stomach 0.38 (gastric pits), small intestine 0.20 and esophagus 0.18 (villi are projections and folds are folds — there it is a whisper that only breaks the texture repeat). Verified: per-biome values reach the material (esophagus 0.18, not the 0.35 default), the effect reads on the wall at gameplay distance, and world.hash() is byte-identical (bea3807c) before and after — this is pixels only, the determinism law is untouched. Not measured: frame cost on real hardware. Nine hashes per wall pixel is not free and the budget is 60fps on mid laptops; if it bites, the honest lever is dropping the low-gain biomes to 0 (which compiles it out entirely) rather than cheapening the shader. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
92 lines
3.8 KiB
JavaScript
92 lines
3.8 KiB
JavaScript
// world/biomes.js (Lane A) — the biome registry. Palette/fog values are transcribed from
|
|
// ART_BIBLE.md §Biome palettes; gameplay defaults (flow, coatDrain) are sane seeds that
|
|
// Lane C overrides per-segment in level JSON (`segments[].flow`). C owns the tuning, this
|
|
// owns the look.
|
|
//
|
|
// Canonical ids — level JSON `segments[].biome` must be one of these:
|
|
// oral · esophagus · stomach · small_intestine · large_intestine · appendix
|
|
// Unknown id => NEUTRAL fallback + one console warning, never a crash.
|
|
//
|
|
// `wave.amp` is displacement in units, inward, at the crest — and it is a GAMEPLAY number, not
|
|
// just a look: world.wallRho() subtracts (amp + breathe) as its conservative margin, so raising
|
|
// it narrows Lane B's flight envelope. Esophagus 1.4 was measured in the harness, not guessed:
|
|
// the stub's 0.9 renders as a barely-legible ripple, and GDD §2 makes riding a crest for boost
|
|
// the level's signature mechanic — B cannot surf a crest the player can't see. 1.4 reads as
|
|
// distinct rings and still leaves ~78% of a radius-10 tube flyable. The other biomes are scaled
|
|
// in proportion and are UNVERIFIED until each one is actually built and eyeballed.
|
|
|
|
export const BIOMES = {
|
|
oral: {
|
|
cells: 0.5, cellScale: 6.0, // squamous epithelium IS a cobblestone pavement — the strongest case in the body
|
|
id: 'oral',
|
|
palette: { tint: 0xa8c4d8, rim: 0xdff2ff, void: 0x06090e },
|
|
fog: 0.016, // clinical, bright, tutorial-readable => you can see across the cavity
|
|
flow: 5,
|
|
coatDrain: 0.15,
|
|
wave: { amp: 0.5, breathe: 0.10 }, // saliva tides, not real peristalsis
|
|
},
|
|
esophagus: {
|
|
cells: 0.18, cellScale: 7.0, // ribbed longitudinal folds, not a pavement: barely a whisper, just to break the repeat
|
|
id: 'esophagus',
|
|
palette: { tint: 0x1e6e64, rim: 0x5affd2, void: 0x02100d },
|
|
fog: 0.028,
|
|
flow: 14,
|
|
coatDrain: 0.5,
|
|
wave: { amp: 1.4, breathe: 0.15 }, // the signature: ribbed rings rushing past (measured)
|
|
},
|
|
stomach: {
|
|
cells: 0.38, cellScale: 6.5, // gastric pits — a pitted field reads as cells at this scale
|
|
id: 'stomach',
|
|
palette: { tint: 0xb0571e, rim: 0xffb13a, void: 0x120801 },
|
|
fog: 0.020,
|
|
flow: 4,
|
|
coatDrain: 2.2, // the acid sea: brutal in open acid (GDD §Player systems)
|
|
wave: { amp: 0.7, breathe: 0.25 }, // churn, not transit
|
|
},
|
|
small_intestine: {
|
|
cells: 0.2, cellScale: 7.5, // villi are PROJECTIONS, not a pavement; keep it under D's texture
|
|
id: 'small_intestine',
|
|
palette: { tint: 0x7a2a6e, rim: 0xff6ad5, void: 0x0d0312 },
|
|
fog: 0.050, // dense: villi forest occludes sightlines
|
|
flow: 9,
|
|
coatDrain: 0.8,
|
|
wave: { amp: 1.5, breathe: 0.18 },
|
|
},
|
|
large_intestine: {
|
|
cells: 0.42, cellScale: 6.0, // smooth mucosa under biofilm — the cells are the visible structure here
|
|
id: 'large_intestine',
|
|
palette: { tint: 0x3a4a26, rim: 0x9dff4a, void: 0x050702 },
|
|
fog: 0.075, // darkness is the mechanic here; scanner light is the safety bubble
|
|
flow: 5,
|
|
coatDrain: 0.6,
|
|
wave: { amp: 1.2, breathe: 0.2 },
|
|
},
|
|
appendix: {
|
|
cells: 0.48, cellScale: 5.5, // the biofilm reservoir: mats of cells are literally the subject
|
|
id: 'appendix',
|
|
palette: { tint: 0x8a7020, rim: 0xffe066, void: 0x0a0800 },
|
|
fog: 0.030,
|
|
flow: 2,
|
|
coatDrain: 0.3,
|
|
wave: { amp: 0.5, breathe: 0.12 },
|
|
},
|
|
};
|
|
|
|
const NEUTRAL = {
|
|
id: 'neutral',
|
|
palette: { tint: 0x557066, rim: 0x9fd8c8, void: 0x050a08 },
|
|
fog: 0.03, flow: 10, coatDrain: 0.4, wave: { amp: 0.9, breathe: 0.15 },
|
|
};
|
|
|
|
const warned = new Set();
|
|
|
|
export function biome(id) {
|
|
const b = BIOMES[id];
|
|
if (b) return b;
|
|
if (!warned.has(id)) {
|
|
warned.add(id);
|
|
console.warn(`[world] unknown biome "${id}" — falling back to neutral. Valid: ${Object.keys(BIOMES).join(', ')}`);
|
|
}
|
|
return NEUTRAL;
|
|
}
|