ALICE-SDF
Signed distance functions for Rust. A shape is a tree of primitives, CSG operations, transforms and modifiers. The crate evaluates the tree on the CPU (scalar, SIMD, BVH and JIT evaluators), transpiles it to GLSL, WGSL, HLSL and Metal, and turns it into meshes and file formats.
English | 日本語
The same tree drives every backend, and the CPU evaluators return the same bits as each other on every platform CI tests. That makes the tree usable as the single description of a shape: the shader that renders it, the collider that a physics engine queries, and the mesh that is exported or printed are all computed from it, not from separate approximations.
It is not a mesh modeller or a renderer. The GPU shaders are not bit-exact with the CPU (they agree within a tolerance), the value after some modifiers (twist, bend, displacement and similar) is a bound on the distance rather than the distance itself, and turning a field into a fine mesh costs time and memory that grow with the resolution.
Contents
- Installation
- Example
- Determinism
- What is included
- Validation and known defects
- Cargo features
- Bindings
- Performance
- Minimum supported Rust version
- Building and testing
- Related crates
- License
Installation
Without the command-line tool (the cli feature, on by default):
Python bindings are on PyPI:
Example
A sphere with a box cut out of it, evaluated, compiled and meshed. The same
code is the crate-level doctest in src/lib.rs, so it is compiled and run by
cargo test.
use *;
// A unit sphere minus a box (box3d takes full extents)
let shape = sphere.subtract;
// Signed distance: negative inside, zero on the surface, positive outside
let p = new;
let d = eval;
assert!;
// Compiled to bytecode for repeated evaluation, with the same bits
let compiled = compile;
assert_eq!;
// A triangle mesh by marching cubes
let mesh = sdf_to_mesh;
assert!;
More programs are in examples/, and a longer walkthrough
(recipes, Python, the LOL language) is in
docs/GETTING_STARTED.md.
Determinism
The CPU evaluators (the tree evaluator, compiled scalar, 8-wide SIMD, BVH and the Cranelift JIT) return bit-identical distances for the same tree and point. Two rules make that hold across platforms:
- Every transcendental (
sin,atan2,exp,powf, …) goes throughalice-det-math, never the platformlibm. a * b + cis always two roundings; nothing is fused into a multiply-add.
scripts/det_math_guard.py fails CI on a platform libm call or a mul_add
in the evaluator and law directories.
| Test | What it pins | Where it runs in CI |
|---|---|---|
tests/test_det_parity.rs |
every CPU evaluator against the tree evaluator, bit for bit | macOS (ARM64), Linux (x86_64), Windows (x86_64); the JIT with --features jit |
tests/test_det_golden.rs |
a SHA-256 of the tree evaluator's bits per corpus shape | the same three |
tests/test_gpu_law_parity.rs |
WGSL against the CPU within a tolerance; axis ties of atan2 exactly |
Linux, on a software Vulkan device (lavapipe) |
Not covered. wasm32 is built in CI but the tests above are not run on
it. The GPU shaders (WGSL, GLSL, HLSL, Metal) are a tolerance domain, not a
bit-exact one. Targets that do not follow IEEE 754 for the basic operations,
and builds with fast-math style flags, are outside the guarantee.
Determinism is not correctness. Matching bits say every machine computes the same numbers; whether the numbers are right is checked separately, see Validation and known defects.
What is included
Every public module, grouped by area with a one-line summary and the feature it
needs, is listed in docs/MODULES.md. API details are on
docs.rs.
| Area | Highlights |
|---|---|
| Shapes | primitives including Platonic and Archimedean solids, TPMS surfaces and extruded 2D shapes; MetricBall, whose norm is a parameter |
| Operations | union, intersection, subtraction and their smooth, chamfer, stairs, exponential and column variants; XOR, morph; MetricBlend |
| Transforms and modifiers | translate, rotate, scale, projective, lattice deformation, skinning; twist, bend, repetition, mirror and symmetry folds, displacement, shell, IFS |
| Evaluation | tree evaluator, compiled bytecode (scalar, SIMD, BVH), Cranelift JIT, GPU compute through wgpu; interval arithmetic, analytic and automatic gradients, Lipschitz bounds |
| Shader output | GLSL, WGSL, HLSL, Metal (from the WGSL output through naga), BlinkScript, and dependency-free Rust source |
| Meshing | marching cubes (uniform, adaptive, GPU), dual contouring, decimation, LOD chains, manifold repair, UV unwrap, meshlets, meshopt-compatible codecs |
| File formats | .asdf / .asdf.json trees; OBJ, glTF, FBX, USD, Alembic, STL, PLY, 3MF, STEP, IGES, MagicaVoxel, Gaussian splats, OpenVDB |
| Analysis | printability (erosion proof with a three-valued verdict, wall thickness, overhang), volume and surface area, tight bounding boxes, SDF-to-SDF collision |
| Worlds | sparse voxel octree, voxel destruction, terrain with erosion, cone-traced global illumination |
Validation and known defects
Tests in tests/ compare results with closed-form values or with an
independent computation: smooth operations, metric fields, interval enclosures
(test_interval_soundness.rs), tight bounds, printability, mesh orientation and
topology, STEP export, the meshopt codecs against the reference library's
vectors, and file-format round trips. Shader output is compiled with naga (and
Metal) in CI. Golden hashes only detect change, so they are kept separate from
these tests.
docs/oracle-status.md is generated from tests/ and
lists every test by status, including tests kept red on purpose
(#[ignore = "known defect: …"]) until the implementation is fixed.
docs/wiring-status.md lists public items that
nothing outside the tests calls, matched by name. scripts/wiring_guard.py
fails CI when a new one appears without a reason.
docs/integration-status.md does the same with
references resolved by rust-analyzer (scripts/scip_reach.py), so a same-named
item elsewhere does not count as a caller; CI fails on a new public item that
no example, binding or other module reaches.
docs/node-support.md lists, for every SdfNode
variant, which backends handle it: the tree and interval evaluators, the
bytecode compiler, both JITs, the Metal and Rust emitters, and the C and Python
constructors. tests/test_node_backend_matrix.rs fails CI when a cell changes
without the table, and when a variant has no test entry.
scripts/ci_test_coverage_check.py fails CI when a test file gated on a feature
is not run by any CI step with that feature, so a feature-gated test cannot
report green by running zero tests.
On every push that changes the library, CI (.github/workflows/bake.yml) builds
meshes on the GPU (lavapipe) and the CPU for a few scenes with
examples/bake_assets, together with glTF,
.abm, .nanite, the SDF tree and its bytecode and the collider data (tight
AABB, volume, centre of mass, inertia tensor). It checks the files from disk
(watertight, GPU and CPU meshes agree, vertices on the surface, closed-form
volume and inertia) and keeps them as a workflow artifact.
Cargo features
Features marked AGPL link a crate licensed AGPL-3.0-or-later; see
License. All other features, including the defaults, pull in only
permissively licensed crates.
| Feature | Default | Description |
|---|---|---|
cli |
yes | The alice-sdf command-line tool (clap). |
image |
PNG / JPEG decoding for heightmaps and texture fitting. | |
texture-fit |
Fit a bitmap texture with procedural noise formulas. Implies image and cli. |
|
jit |
Native evaluation through Cranelift (scalar and 8-wide). | |
gpu |
GPU evaluation and WGSL output through wgpu. | |
gpu-mesh |
Marching cubes on the GPU. Implies gpu. |
|
volume |
Bake a field into a 3D texture. Implies gpu. |
|
glsl |
GLSL output (Unity, OpenGL, Vulkan, Shadertoy). | |
hlsl |
HLSL output (Unreal Engine, DirectX). | |
msl |
Metal Shading Language output, converted from WGSL with naga. Implies gpu. |
|
blinkscript |
BlinkScript output for Nuke. Implies hlsl. |
|
rust |
Dependency-free Rust source (fn sdf, fn normal) bit-identical to eval_compiled, for build.rs. |
|
all-shaders |
gpu, glsl, hlsl, msl and blinkscript. |
|
svo |
Sparse voxel octree. | |
svo-gpu |
Sparse voxel octree with GPU support. Implies svo and gpu. |
|
destruction |
Voxel destruction. | |
terrain |
Heightmap terrain with erosion and caves. | |
gi |
Cone-traced global illumination. Implies svo. |
|
aaa |
volume, gpu-mesh, svo-gpu, destruction, terrain and gi. |
|
ffi |
C ABI for C, C++, C#, Unity and Unreal Engine. | |
unity |
ffi and glsl. |
|
unreal |
ffi, hlsl, glsl and gpu: what the Unreal Engine plugin calls. |
|
python |
Python bindings (PyO3 + NumPy). | |
godot |
Godot 4 GDExtension. | |
wasm |
WebAssembly bindings through wasm-bindgen (built for wasm32 only). |
|
openvdb |
OpenVDB float grid input and output. | |
physics |
AGPL. SDF colliders and simulation modifiers for alice-physics, and LiveSdf: one editable shape shared by the world's collider, a world participant and a chunked render mesh that re-meshes only the chunks a change reaches. LiveSdf::apply_world_contacts turns the contacts the world recorded in the last step into craters, and the world wakes resting bodies when the shape changes. |
|
codec |
AGPL. Volume compression with alice-codec. |
|
sdf-cache |
AGPL. Evaluation cache with alice-cache. |
|
asp |
ALICE Streaming Protocol packets with libasp (its default features only). |
|
font |
Glyph outlines from alice-font. Inert on crates.io: also needs --cfg alice_font_bridge and a local alice-font. |
Bindings
| Target | Where | Notes |
|---|---|---|
| C / C++ | include/alice_sdf.h |
--features ffi |
| C# / Unity | bindings/AliceSdf.cs, unity-sdf-universe/ |
P/Invoke over the C ABI |
| Unreal Engine 5 / 6 | unreal-plugin/ |
--features unreal |
| VRChat | vrchat-package/ |
a VRChat package: SDF surfaces players can walk on and collide with |
| Godot 4 | docs/GODOT_GUIDE.md |
--features godot |
| Python | python/, docs/PYTHON_GUIDE.md |
--features python; NumPy batch evaluation and mesh export |
| WebAssembly / Three.js | docs/WASM_GUIDE.md, npm/ |
--features wasm |
| iOS / Android | mobile/ |
XCFramework and Kotlin bindings over the C ABI |
| Bevy, Blender, Houdini, Maya, Nuke, Cinema 4D, OpenXR, visionOS | bindings/, docs/INTEGRATIONS.md |
reference integrations |
CI checks the C ABI against its consumers: scripts/abi_decl_check.py and
scripts/unreal-abi-check.sh compare every exported function with the C
header, the C# bindings and the Unreal Engine plugin.
The Text-to-3D server and the ALICE-View viewer are applications built on the
crate; see docs/TEXT_TO_3D.md.
Performance
Benchmarks are in benches/ (criterion):
No numbers are listed here. The figures in older documents were measured before the evaluators were made bit-exact (which removed fused multiply-adds) and have not been measured again since. Run the benchmarks on your target before quoting a number.
Minimum supported Rust version
Minimum supported Rust version: 1.85 (the rust-version in Cargo.toml).
A CI job checks the library with exactly this version for the default features and the docs.rs feature set. Raising the MSRV is a minor-version change, never a patch.
Building and testing
scripts/preflight.sh reproduces the CI checks locally (--quick skips the
integration and oracle tests).
Related crates
| Crate | Role |
|---|---|
| alice-det-math | the deterministic transcendental functions this crate and ALICE-Physics both use |
| ALICE-LOL | a language that parses to the same SdfNode tree, with a law verifier (see Getting started) |
| ALICE-Physics | deterministic physics; with the physics feature it collides against the same field that is rendered |
| ALICE-View | a real-time viewer for .asdf files |
Keep a single version of alice-det-math in your dependency graph. Two
versions mean two implementations of the same function, and determinism is
lost. Check with cargo tree -i alice-det-math.
Release history is in CHANGELOG.md. Planned work is in
docs/ROADMAP.md.
License
The crate is dual-licensed under MIT OR Apache-2.0
(LICENSE-MIT, LICENSE-APACHE).
The physics, codec and sdf-cache features link crates licensed
AGPL-3.0-or-later. A build that enables any of them is subject to the AGPL as
a whole. The default features and every other feature do not.
The Unity integration (unity-sdf-universe/) and the
VRChat package (vrchat-package/) are under the ALICE
Community License (LICENSE-COMMUNITY): free for personal
use, game development (including commercial games), education and open source;
a commercial licence is required for infrastructure services (cloud, metaverse
platforms, streaming) as that licence defines them. Commercial licence enquiries:
contact@extoria.co.jp
Content you create with the crate (trees, meshes, worlds) is yours.
Many distance functions follow published forms by Inigo Quilez, Mercury (hg_sdf) and Ken Perlin; the list and scope are in THIRD-PARTY-NOTICES.md.
Copyright (C) 2025-2026 Moroya Sakamoto