6.4 KiB
CultMath tapes: interval-pruned field evaluation on CPU and GPU
Status: steps 2 and 4 (graph, C# evaluator, HLSL interpreter) unparked on
2026-10-14 (ruling tape-unparked-for-trophic-graphs, which supersedes
tape-target-unparks-when-asura-stable); their model page and cut sequence are
docs/cultmath-interval-ground-cut.md, "Pass 7". Steps 3 and 5 (pruning,
meshing) stay parked. The affine-forms
piece was unparked on 2026-10-03 (ruling affine-forms-unparked) and is on main
(156782da), alongside step 1's intervals; its map and as-built record are in
docs/cultmath-interval-ground-cut.md. This note records the direction for the
parked steps so they can be picked up without re-deriving it.
Intent
Evaluate large implicit fields, meaning deeply nested CSG trees of brushes with thousands of nodes, cheaply enough to mesh at many levels of detail and to raymarch. The operator's words (2026-10-02): "I would love to design a space station out of a grammar of nested brushes, and have the ability to automatically mesh it at multiple levels of detail so I can get arbitrarily close to its tiny details without melting my GPU."
GameCult has no deep CSG trees today because nothing could evaluate them cheaply. The capability comes first, and the content follows.
Prior art
Fidget by Matt Keeter
(MPL-2.0, Rust, v0.5.1 on 2026-09-27; repo mkeeter/fidget).
- It compiles an expression to a register-allocated bytecode tape.
- It evaluates that tape as points, SIMD batches, intervals, and forward-mode gradients.
- The central trick is interval evaluation over a region. When it proves that
one operand of a
minormaxalways wins, the tape for that region is rewritten without the other branch. In the project's example, the tape shrinks from 254 clauses to about 20 at pixel level. fidget-jittargets x86-64 and AArch64.fidget-wgpuhas a WGSL tape interpreter, interval ops and tape simplification on the GPU (interval_ops.wgsl,tape_interpreter.wgsl,tape_simplify.wgsl).fidget-meshimplements Manifold Dual Contouring. It is known to be weak on thin features.- Halfspace is the IDE codesigned with
fidget-wgpu(Rust, egui and wgpu, MPL-2.0).
Chosen shape (option c)
The ideas are ported into CultLib and owned here. Fidget is not a dependency.
Unity renders HLSL on its own graphics backend, so fidget-wgpu cannot run
inside it.
Three options were weighed on 2026-10-02:
| Option | What it is | Trade |
|---|---|---|
| a | Fidget as a Rust native plugin in Unity | Fastest demo; costs per-platform native builds, an FFI boundary, and an upstream that warns of breaking changes |
| b | Offline bake with a Rust tool; ship meshes | Simplest; the baked depth caps how close a viewer can get |
| c | CultLib owns tape, interval and pruning in C# and HLSL | Most coherent end state; the largest code liability we would own |
The operator parked (c). An (a) spike to validate authoring and LOD behaviour before owning code was suggested but not ruled.
Sketch, to be replaced by the target pass:
-
CultMath
intervalin C# and HLSL with parity tests:- arithmetic,
min/max,smin,sqrt,clampandsmoothstep; - interval or Lipschitz bounds for every CultMath noise primitive.
This step needs no tape. It stands alone, and is the first cut to take even if the rest stays parked.
- arithmetic,
-
Tape: an expression graph lowered to bytecode, with point, interval and gradient evaluators in C#. Gradients reuse CultMath's analytic-gradient primitives, which Asura cut 2a built.
-
Pruning: per-region tape simplification driven by interval results.
-
HLSL interpreter for the same bytecode, with interval ops and pruning. Fidget's MPL-2.0 WGSL is the reference. MPL code keeps its own MPL-headed files, as Phacelle does.
-
Meshing: an octree of chunks with seams stitched between LOD levels.
- The default is surface nets (GameCult.Geometry, Asura Cut 2) plus
Asura's tile pass: Newton refinement onto
f = 0, then crease snapping from field gradients (Asura Cut 6c). - The operator's lean (2026-10-02) is that gradient work beats dual contouring here. Thin authored bevels can be shaded by their analytic normals, and the refined positions can be iterated further.
- Dual contouring is not planned. The tile pass on station brushes is its test.
- The default is surface nets (GameCult.Geometry, Asura Cut 2) plus
Asura's tile pass: Newton refinement onto
Truth and lowerings
The field is data: a typed CultCache document holding the expanded tree. A generator, such as a brush grammar, expands into that document, and everything downstream caches it. The CPU evaluator, the HLSL interpreter, the mesher and collision are all lowerings of that one document. This is how "one implementation of the field" survives having both CPU and GPU evaluators. Asura's invariant 2 had to forbid CPU evaluation because its field is HLSL source.
Known consumers
- Aetheria volumetric raymarching (clouds, nebulae). Step 1 alone gives it
empty-space skipping. Coverage and shape terms carry the culling, because
detail octaves only bound to ±amplitude.
- Prerequisite: Aetheria's shaders must use CultMath noise, not their own copies. That is already owed at Aetheria's CultMath pin bump (see the Asura cut map, snoise release follow-ups).
- Space stations from a brush grammar, meshed in LOD chunks around the camera. This is a separate project with its own target. This campaign supplies its evaluator.
- Asura does not need this campaign. Its field is noise-dominated, and its
A_maxshell and band-limiting already give the cheap culling.
Decided since the unpark, and what stays open
- The spike-or-(c) choice was settled by the operator's unpark: the tape
unparked for Aetheria's trophic species graphs (ruling
cultmath-tapes:ruling:tape-unparked-for-trophic-graphs). - Interval representation: affine forms for noise and warp, unparked on
2026-10-03 (ruling
cultmath-tapes:ruling:affine-forms-unparked): one shared symbol, mapped indocs/cultmath-interval-ground-cut.md, "Pass 5". - Register model: the HLSL interpreter keeps its registers in groupshared
memory, a slice per thread, linear-scan allocated at lowering (ruling
cultmath-tapes:ruling:tape-register-model-ruled; research indocs/research/tape-register-model.md). - Open: whether the brush-grammar station project lives in Aetheria or in
its own repo (follow-up
cultmath-tapes:follow_up:brush-grammar-station-repo, raised as an operator question when a station cut reaches the frontier).