Status: Draft · proposed for v4.0 cycle Author: project owner (with audit) Last updated: 2026-05-25
"It should look like a real electron-microscope image of the chemistry we're simulating — not a viridis heat-map on a 80×80 pixel grid."
The v3.x line earned scientific credibility (real Eigen-Schuster ODE, Helfrich bending, Miyazawa-Jernigan landscape, pathway-graph LUCA, coupled 12-stage pipeline). The next jump is representational: the output should look like an actual scientific instrument view — a live SEM feed of the chemistry — so the visual story matches the mathematical truth underneath it.
The reference image (docs/ideal_sem_view.png, the user-supplied
target) shows what we're aiming for:
- A monochrome / warm-sepia "instrument" palette — not coloured heat maps.
- Depth-shaded textured surfaces — every pixel reads as a 3-D micrograph fragment with directional lighting and ambient occlusion.
- Recognisable biological forms — spherical protocell-like blobs catching light, fibrous networks, granular substrate.
- A "LIVE SEM FEED" frame around the canvas, scale-bar microcopy underneath, the existing 3-column layout (wall-label · canvas · controls).
- A bottom marginalia ticker walking through the chemistry-to-life story.
The goal is for a viewer to look at the screen and believe they are watching a microscope view of real abiotic chemistry.
- SEM-grade rendering of all 12 stages of the extended pipeline.
- Maintains scientific fidelity — the underlying simulation is unchanged. Every pixel of the SEM image is still driven by real reaction-diffusion / hypercycle ODE / pathway-graph values.
- Runs on the same hardware the desktop client already targets (CPU + Tk + numpy + PIL; no mandatory GPU).
- A GPU acceleration path is wired in but optional — the project stays installable with the existing minimal dependency set.
- The "LIVE SEM FEED" framing extends to the web client too, so both clients share the same instrument aesthetic.
- Volumetric / true 3-D ray-traced rendering. We're producing SEM-style 2.5-D depth-shaded imagery, not a volumetric simulation.
- Online AI image-to-image post-processing. Stable-Diffusion-style refinement is a stretch goal (Phase 5), not the baseline.
- Replacing the underlying simulation. Every visible feature must still be derivable from the engine's existing fields and entities. No "decorative" structures that aren't in the math.
- Photo-real microbiology of extant cells. The look is abiotic chemistry, not modern biology — protocells and chemistry, not E. coli.
| Persona | Need | What v4.0 buys them |
|---|---|---|
| Educator showing the origin-of-life arc to a class | A demo that's not obviously a "toy" so the science lands | Photographic SEM view that students immediately recognise as a real instrument feed |
| Researcher validating the science model | Visual confirmation that the chemistry is doing what it should | Depth-shaded view surfaces real spatial structure (vesicle thickness, protocell membrane curvature, RNA-cloud density gradients) that the viridis colourmap was flattening |
| Outreach team demoing the project at conferences | A piece that holds a viewer's attention for > 5 seconds | Living SEM feed + chapter-card story narrative + AAA poster identity |
| Scientific illustrator / author licencing imagery | A piece they can put in a textbook caption without disclaiming "schematic" | Output that reads as instrument-grade |
Every continuous field stage (1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12) must render its primary scalar field as a height-mapped, lit, textured surface, not a flat colourmap.
- Input: the stage's chosen scalar field (e.g. Gray-Scott
v, coacervateφ, vent acetate, mineral polymer, LUCA fitness). - Process: compute gradients → surface normals → Lambertian + ambient + specular shading under a fixed directional light → add a procedural micro-texture (multi-octave noise) → tone-map to a warm sepia / cool monochrome ramp → upscale with edge-aware interpolation (LANCZOS).
- Output: an 8-bit RGB image that reads as a 3-D micrograph.
The canvas is reframed as an instrument feed, not a "viewport":
- Crosshair / reticle overlay in 1-px hairline teal at the canvas centre, with tick marks at the four quadrant midpoints — gives the image the look of a microscope field.
- "LIVE SEM FEED · Stage N — name" badge in the upper-right corner, monospace microcaps, tracked.
- Scale-bar microcopy below the canvas: "1 μm" with a hairline bar (the bar length is scaled to the grid extent so it stays physically plausible across grid resizes).
- Vignette at the corners (~10 % darkening) to suggest a curved instrument aperture.
Each stage has a stage-specific sprite library that's composited on top of the depth-shaded background:
| Stage | Sprite | Driven by sim |
|---|---|---|
| 0 — Soup | tiny coloured granules + larger spherical protocell blobs | NaturalSelectionRule cells (amoeba flag → bigger sphere, is_new → fresher edge) |
| 1 — Gray-Scott | self-replicating spots as bone-white circular forms catching light | the v-field thresholded |
| 2 — Vents | a vertical mineral-honeycomb chimney slice | chimney column mask + porous overlay |
| 3 — Vesicles | translucent membrane spheres with phospholipid bilayer rings | the lipid field thresholded + Helfrich curvature |
| 4 — Protocell selection | filled spheres with internal genome dots | the Protocell list |
| 5 — RAF | a fibrous reaction-network with glowing autocatalytic loops | RAF graph nodes + edges |
| 6 — Chirality | left-handed / right-handed helical pairs (L bone-filled, D outlined) | left vs right field arg-max |
| 7 — RNA world | concentric isobars of replicator density around the master | seq-field Hamming-binned |
| 8 — Genetic code | 4×4 codon matrix dots embossed onto a translation table surface | code field consensus |
| 9 — Coacervates | liquid-liquid droplet blobs with proper internal contrast | φ-field thresholded with Cahn-Hilliard ridges |
| 10 — Vesicles | re-uses Stage 3 sprite library | lipid field |
| 11 — Selection | re-uses Stage 4 sprite library | Protocell list |
| 12 — LUCA | a rooted phylogenetic tree etched into the surface, plus the 12 essential-gene nodes lit | LUCA core constellation + genome-derived tree |
The sprites are rendered once at startup (or lazy-loaded), tinted to match the stage's SEM palette, then alpha-composited per frame.
Two factory presets, picker in View ▸ SEM palette:
warm-sepia(default — matches the reference image). Background is desaturated dark brown (#2a221c → #4a3b30); highlights bone-cream (#e6dcc5); single teal accent reserved for the "LIVE SEM FEED" badge and the on-canvas reticle.cool-mono(alternative). Background near-black (#0a0e16); highlights bone-white (#e6e0d0); accent teal (#39d4c8). This is the existing Catalytic Silence palette extended into 3-D shading.
Both must be colourblind-safe — verified by simulating CVD palettes
via colorspacious.
- 60 × 60 grid, default settings, sustains 20 FPS on a 2020 ThinkPad-class laptop (Intel UHD, no discrete GPU) without batching.
- 120 × 120 grid, default settings, sustains 20 FPS on the same hardware via Phase-2 numpy vectorisation OR Phase-4 GL acceleration if the user opts in.
- The rendering pipeline must never block the engine step loop — rendering runs in a worker thread with a single-frame buffer to keep the UI responsive even at slow grids.
If the user has a Pillow version without LANCZOS, or no scipy for
fast Gaussian blur, or a Tk too old for high-bit-depth PhotoImage,
the renderer must degrade to the v3.6 viridis path rather than
crash. Detection is done at startup; a one-time toast informs the
user that SEM mode is unavailable and why.
A View ▸ SEM mode checkbox lets the user flip between v3.6 viridis
rendering and v4.0 SEM rendering. Both produce scientifically
equivalent imagery; SEM is just a different rendering path. Default
is SEM mode on.
PNG, GIF, and snapshot exports work identically under SEM mode. A PNG export under SEM mode produces a frame indistinguishable from the on-screen view (no "watermarked" or "preview-only" overlays).
- The web client's 3-column layout, also imported into the Tk client via the v3.6 wall-label work, is the canonical composition.
- Canvas dominates the centre, 720 × 720 fixed in Tk, fluid in web.
- Left column: stage wall-label · configuration · readout (per v3.6).
- Right column: parameters · stage · export — as tabs in web, as the scrollable column in Tk (per v3.6 deferred-L2 rationale).
- Bottom: transport bar (PLAY · STOP · STEP · RESET · RECORD GIF) + FPS slider + scrub bar + marginalia ticker.
- Display serif (Italiana / Cormorant Garamond) for stage title.
- Italic serif (Crimson Pro / Cormorant italic) for citations.
- Monospace (IBM Plex Mono / JetBrains Mono) for all apparatus marks (LIVE SEM FEED, scale-bar, stat readouts).
- All caps tracked microcopy (
P L A T E I · M M X X V I) for section labels.
- The "LIVE SEM FEED" badge has a slow 2.2-s opacity pulse (matches the v3.6 status-dot pulse) tied to the playback state.
- The crosshair reticle is static.
- The scale-bar updates only when the grid resizes.
- The marginalia ticker advances on chapter transitions (existing v3.6 chapter-card mechanism stays).
Targets F1, F2, F4, F6, F7 on existing hardware.
- New module
cellauto/renderer_sem.py. ClassSemRendererwith the samerender(state)interfaceFieldRendererhas so the existing app.py + GUI doesn't need to know which renderer is active. - Inputs: the rule's existing
render_rgb(state)output OR a newrender_height(state)method returning a single-channel float field;SemRendererprefers the latter when available. - Shading pipeline in numpy:
- Gaussian-blur the height-field at σ = 0.7 to suppress single-pixel artefacts.
- Sobel-filter the smoothed field for ∂H/∂x, ∂H/∂y.
- Build a normals tensor N = normalise((-∂H/∂x, -∂H/∂y, 1)).
- Lambertian: I = clip(N · L, 0, 1) with light direction L = normalise((0.4, 0.3, 0.85)).
- Ambient: I += 0.2.
- Specular: add (N · H)^32 with H = halfway-vector for a small highlight.
- Ambient occlusion: subtract α * laplacian(H) clipped to non-negative to darken creases.
- Multi-octave Perlin / value noise overlay at 6 % opacity.
- Tone-mapped through a 256-entry warm-sepia (or cool-mono) LUT.
- LANCZOS upscale from grid resolution to 720×720.
- Composited with the stage's sprite library (F3) via PIL alpha-compositing.
- Vignette pass and crosshair / scale-bar overlay (F2).
- Performance target verified by
tools/bench_sem_renderer.py: 20 FPS @ 60×60 grid on CPU.
Targets F3 across all 12 stages.
- Generate the sprite library once via PIL + procedural shapes
(or via the whipgen MCP for the hero forms). Save to
cellauto/assets/sprites/<stage>/<form>.png. SemRendererlazy-loads sprites; tints them to the current palette via PILImageEnhance.Color+ a colour-multiply.- Spatial placement comes from the simulation state (which we already track per-stage).
- Add
tests/test_sem_renderer.pypinning that (a) every stage produces a non-trivial image, (b) zeroing the sim field produces a near-uniform background, (c) the SEM and viridis renderers produce the same step count.
Tune the sprite library + height-field interpretation per stage until every one is recognisably "its own kind of microscopy" (crystal mineral surfaces for Stage IV, liquid droplets for Stage IX, lipid bilayer interferograms for Stages III + X, etc.).
Targets F5 at higher grid sizes.
- Add an optional
modernglextra (pip install cellauto[gpu]). - Re-implement the Phase-1 shading pipeline as a single GLSL fragment shader.
- The renderer auto-selects GPU if
modernglis importable AND the user hasn't opted out viaView ▸ SEM mode ▸ Force CPU. - Maintains exact pixel parity (golden-image regression test) so screenshot tests don't break.
Optional, opt-in, never required.
- Add a
tools/sem_refine.pyscript that takes a CPU/GPU SEM render and runs it through a fine-tuned image-to-image diffusion model with the prompt "scanning electron micrograph, abiotic chemistry, monochrome, depth-shaded" at strength 0.35. - Available via
File ▸ Export refined PNG…for hero shots only (too slow for live playback). - Documented as a research feature; not part of the default UX.
| Cycle | Deliverable | Acceptance |
|---|---|---|
| v4.0.0 | Phase 1 — SemRenderer shipped, View ▸ SEM mode toggle, palette picker, all 12 stages render in depth-shaded sepia |
20 FPS @ 60×60 CPU, all four CI gates green, screenshot regression on Stage 1 demo |
| v4.0.1 | Phase 2 — sprite library for stages 0, 1, 3 | Side-by-side comparison: each of those three stages reads as a microscope view, not a screenshot |
| v4.1 | Phase 3 — sprite libraries for the remaining nine stages | Full 12-stage SEM gallery committed to docs/generated/sem_<stage>.png |
| v4.2 | Phase 4 — optional moderngl GPU path |
20 FPS @ 240×240 grid on GPU; CPU fallback unchanged |
| v4.3 | Phase 5 — opt-in AI refinement | One Stage 1 hero shot exported at fine-tuned diffusion quality |
These have come up in conversation and are deliberately NOT v4.0 work:
- Replacing Tkinter with PyQt or a web-only client. The existing Tk app is shipped, tested, and accessible; the SEM renderer is a backend swap, not a UI rewrite.
- Voxel-grid 3-D simulation. The chemistry stays 2-D; the rendering is 2.5-D (height-mapped) for cost reasons. A volumetric upgrade is a v5.0 conversation.
- Mandatory GPU. No user gets locked out because they're on a laptop without a discrete graphics card.
cellauto gui --rule abiogenesis-pipelineshows the canonical 5- stage pipeline running in SEM mode by default.View ▸ SEM modetoggles between viridis (legacy) and SEM rendering; both paths produce the same step count on the same seed.- The toggle persists across restarts via the existing config file.
- Stage 1 (Gray-Scott) under SEM mode produces an image where:
- the background reads as a textured granular substrate,
- the self-replicating spots read as bone-coloured spheres with directional shading and shadow,
- a crosshair reticle and "LIVE SEM FEED · Stage 1" badge are overlaid.
- The four CI gates (ruff, ruff-format, mypy, pytest) stay green.
- Test count grows by at least 8 (4 SEM renderer pins + 4 palette / fallback pins).
docs/generated/sem_<stage>.pngexists for at least Stage 1, the canonical demo. Generated bytools/render_aaa_visuals.pyrerun under SEM mode.CHANGELOG.mdandREADME.mdcarry the v4.0 entry with a side-by-side "before / after" comparison image.
These are flagged for resolution during v4.0 design:
- Sprite library generation: procedurally with PIL, or via the whipgen MCP, or via a static-asset pack downloaded on first launch? The MCP route gives photographic quality but adds a network dependency at first-render; the PIL route is deterministic but shallower. Likely answer: PIL for v4.0.0, MCP-generated as an upgrade in v4.0.1.
- Height-map source per stage: should every stage expose a new
render_height(state)method (cleaner, more work), or should the renderer derive height from the existingrender_rgbluminance (less clean, no rule changes needed)? Likely answer: start with luminance derivation; allow rules to override withrender_heightfor finer control. - Animation cadence under SEM mode: the CPU shading pipeline at
60×60 may not sustain 20 FPS on the lowest-end target hardware. If
it can't, do we drop to 12 FPS, or do we keep 20 FPS by skipping
shading every other frame? Likely answer: a
View ▸ SEM mode ▸ Reduced qualitycheckbox that drops the shading pipeline to 1/3 of its work (single-octave noise, smaller Gaussian sigma). - Web client coherence: does the web client get an HTML5 Canvas shader port of the same pipeline, or does it stay viridis until the Python server can ship rendered SEM frames at frame-buffer rate? Likely answer: the server renders SEM frames and streams them exactly as it currently does for viridis; no changes needed on the client.
- v3.0–v3.3: built the simulation core (12 stages, real dynamics).
- v3.4: AAA visual identity for static assets (Genesis poster, Twelve Tableaux, stage plates).
- v3.5: honest-gap closure for the simulation correctness (Eigen-Schuster ODE, Helfrich curvature, MJ landscape, pathway-graph LUCA, pipeline coupling).
- v3.6: parity between the Tk client and the Flask web client on UX qualities (wall-label, debounced sliders, batched stepping, toast notifications, pulse animations, reduced-motion mode).
- v4.0 (THIS PRD): SEM-grade live rendering — the visual identity the static v3.4 assets earned, applied to every frame the engine produces.
The arc: real science (v3.0–v3.3) → real visual identity (v3.4) → real coupled science (v3.5) → real UX parity (v3.6) → real rendered science (v4.0).