left-drag orbit · scroll zoom · W wireframe ·
N normals · G grid and domain box · Space pause ·
H hides the HUD, leaving a [H] HUD line ·
1–7 reference field · R re-mesh ·
F12 screenshot (downloads a PNG)
→ ← step through the 48 reorientations · A auto · H markers on the moved vertices
The console carries this run's cross-check against the committed
docs/experiments/p-57.csv: every field, every column, measured
here rather than replayed.
T tape length · [ ] step chunks · B brush gizmos · K chunk boxes · X hand control back to the tour
The first sixty-four frames are the ablation itself — one chunk per frame, 1,571 re-meshes — and the count on the canvas is how far it has got. Nothing else is on screen until it finishes.
The console then carries this run's cross-check against the committed
docs/experiments/p-59.csv, thirteen comparisons including all
sixty-four per-chunk mesh hashes.
← → slide sigma by hand · ↑ ↓ or 1–9 which signal · R back to the loop
The console carries this run's cross-check against the committed
docs/experiments/p-60.csv: the closed-form sweep is recomputed
in your browser and held against every number the CSV publishes.
X f32 sign disagreements · Z the Δ = 0 stratum · V hide the surface · ← → which field · ↑ ↓ resolution
The panel compares this run to the committed
docs/experiments/p-130.csv and
docs/experiments/p-134.csv rows for the same field and
resolution: the (Δ > 0, Δ < 0, Δ = 0) partition, P-131's branch-fire counts, and the normalised
magnitude's range. b*b − 4*a*c at trilinear.rs:246 is Cayley's 2×2×2
hyperdeterminant, exactly (P-127).
← → which surface · ↑ ↓ periods and the voxel ladder · P wrap the seams or not
χ is counted from the welded extraction; the prediction is derived on the fly from a
seven-half-shift symmetry census, not transcribed. The 32-voxel rung is a labelled degenerate
control: it samples the π/4 lattice where Schwarz D cancels to exactly zero (M-48), and
chi_measured − chi_predicted reads its non-manifold edges exactly. The open arm is
judged by its boundary edges, never by χ.
No keys and no HUD: a sphere meshed as eight chunks, on screen, and nothing
else. It is the one example that does not share the demo harness, which is
why the controls above are not listed for it — everything it does is in
examples/quickstart.rs,
and the file is the point rather than the picture.
What it proves here is the same thing it proves natively: eight chunks meshed independently, and the result is still watertight.
1 2 configuration · H the inner hexagon · C the contours · W wireframe only
One cell, meshed twice. Left is the face rule alone — two separate discs. Right adds the interior rule and gets one cylinder, which is what the trilinear interpolant actually does there. The gold ring is the six body saddles Grosso's construction is built out of.
1 2 field · [ ] resolution · C the cell clamp · W wireframe
Surface Nets on the left, Dual Contouring on the right, on the same field, the same grid and the same crossings. The only difference between the two meshes is where a cell's vertex goes, and the HUD measures each side's distance to the true corner every re-mesh: 0.58 cells against 0.01 at 27³. That gap is the entire case for dual contouring.
1–5 field · [ ] resolution · S smoothing passes · W wireframe
The catalog once billed this as "triangle counts differ". They do not, and
the HUD recomputes why on every re-mesh: F_sn − F_mc = 2χ
exactly, on every closed field, because both are pinned to the number of
crossed grid edges. Watch it hold as the field and the resolution change.
WASD walk · mouse to look · Space jump · Shift fast · F fly · H numbers · Tab releases the cursor
You start walking on the rock: gravity pulls you down, the ground holds you up, and a stone face stops you dead. All three come from sampling the field under two spheres rather than from a collision mesh, because a collider built from this terrain is stale the moment you carve — which is every frame you hold the button. Space jumps a full chunk, 2 units, which clears the lip of a pit dug at the large end of the wheel. F switches back to the fly mode this demo used to open in, where gravity is off and Q and E go straight up and down.
The numbers panel starts hidden, because this is a game first and the panel sits on top of the rock you are digging. What stays is a coloured headline naming the mesher — a different colour for each of the eight, in key order — and one line of keys under it. H brings the numbers back.
Hold the left button to carve, the right to fill. The translucent sphere on the rock under the crosshair is the brush that a click would push — orange to carve, cyan to fill — so what you see is what you get, at the surface rather than at a fixed distance in front of your eye. The wheel or [ ] resizes it, Z undoes one brush, X clears the log, C outlines the chunks the last edit re-meshed.
Holding a button carves at a fixed 12.5 edits a second rather than one per frame, and the chunks that fall out of it are re-meshed under a 4 ms per frame budget — nearest to the camera first, with whatever does not fit carried into the next frame. That is the difference between a long stroke that holds its frame time and one that collapses: every sample of every chunk still evaluates every brush in the log, so the only two things that can save you are growing the log more slowly and refusing to pay for all of it at once.
1–8 swap the mesher and re-mesh all 256 chunks with it
— Marching Cubes, the same with the asymptotic decider, Marching
Tetrahedra, Surface Nets, Dual Contouring, Manifold Dual Contouring, Greedy
Quads, and on 8 Marching Cubes again but on the GPU,
as a compute shader through isomesh-gpu. The rendering was
always on the GPU; what moves on 8 is the extraction and,
since GPU-014, the field — the cells are counted and prefix-scanned
and the triangles emitted on the device, and the vertices come back a frame
later rather than in the call that asked for them. The terrain is not one of
the four fields the shader knows how to evaluate, so a chunk's base samples
are uploaded once and every carve after that ships only the
brush log — 64 bytes a brush — to be folded over them on the device. The
numbers panel shows it: base goes to (cached) and
stays there, and the running total of uploaded samples stops growing.
And the honest verdict, because a GPU option invites the assumption that GPU means faster: at this chunk size the CPU wins. A chunk here is 17³ samples, and on an RTX 3090 over Vulkan that row reads CPU 0.06 ms against GPU 0.22 — a fixed ~0.22 ms of per-dispatch setup cannot be amortised over 4,913 samples. The GPU takes the lead at 33³ (0.34 against 0.23), is 9× ahead at 65³ and 37× ahead at 129³, because that GPU column is nearly flat across a 420× rise in cell count. Key 8 is here to show you that shape, not to be the fast one on this grid.
The headline at the top names whichever mesher is running, in its own colour, and the numbers panel prints what the switch cost — which is the only honest way to show that Marching Tetrahedra is three times the triangles. A dimmed "Loading… please wait." panel covers the screen while a switch's 256-chunk backlog drains, because that backlog now drains across frames instead of blocking one.
The mesh is rebuilt while you hold the mouse down, and the two numbers on screen are the ones that matter under load: chunks touched per edit, and E1 — the fraction of the brush's own bounding box that actually changed. M-33 measured 15–36% offline; this is it live.
H hides the whole panel and leaves a single [H] HUD
line behind, so you can look at the rock without reading numbers over it and
still find your way back.
The rock is cracked concrete, textured by the fragment shader rather than by the mesh: an isosurface has no natural parameterisation, so the material samples all three world planes and interpolates between them by the normal. Carve a fresh hole and the new interior surface is textured continuously with the ground around it, across the chunk boundary the brush straddled.
Space pause · [ ] fly speed · 1–3 how much of the world is cave
fBm terrain intersected with a thickened gyroid, so the camera flies
through the rock — under arches, into tunnels, out the far side of a
wall — which a heightfield cannot represent at all. This is the demo that
needs IsomeshPlugin's streaming, and until ✗44 that plugin
panicked on its first chunk in any browser.
It runs at its committed defaults here. The example reads
ISOMESH_* environment variables to override the stream radius
and the frame budget, and a browser has no environment — so every one of
them takes the documented default rather than something a URL chose.
One thing to expect if you open the console on this one: streaming churns
meshes continuously, and Bevy 0.19's bevy_render slab allocator
logs "Use-after-free: attempted to copy element data for an unallocated
key" once per affected mesh — 3,186 times in a 45-second run, measured
on the WebGL2 backend this page served before the eleven demos moved to
WebGPU, so read the count as the shape of the thing and not as today's
figure. The demo streams and renders correctly through all
of it (411 chunks resident, 229,580 triangles). It is upstream of this
repository and it is not suppressed here, because a filter that hides a
renderer's errors would also hide the next real one.