proof-engine

Proof Engine

A Rust rendering engine where every visual is the output of a mathematical function. Glyphs and particles are moved by differential equations and force fields, and drawn in HDR.

cargo add proof-engine
Run a demo Source

FIG. 1The sky example from 16:20 to dusk, captured frame by frame with PROOF_SHOT and played forward and back. Every cell of that sky is a scattering integral.

Nishita sky

Drag the sun.

The sky is 120 by 56 cells. For each one, every frame, nishita_sky::compute_sky_color integrates Rayleigh and Mie single scattering along the view ray and along a second ray toward the sun.

No gradient is painted anywhere. The blue at three o'clock, the orange band at sunset and the dark teal after it are the same integral with the sun somewhere else. The mountains are sums of sines lit by the sky just above the horizon.

The sky demo at 14:48, sun elevation 36.8 degrees
14:48sun elevation +36.8°
afternoondusk

FIG. 2Forty real frames from cargo run --release --example sky. Times and elevations are the ones the demo prints.

FIG. 3cargo run --release --example lorenz. Teal is slow, amber is fast.

Strange attractors

Forty thousand points, one equation.

dx/dt = 10 (y − x)
dy/dt = x (28 − z) − y
dz/dt = x y − 8⁄3 z

Each point is a state advanced every frame by the engine's own RK4 step. Nobody drew the two wings; that is where the equations send the points. The same module carries Rossler, Chen, Halvorsen, Aizawa, Thomas, Dadras and more, and any of them can drive a force field.

examples/lorenz.rs
for p in points.iter_mut() {
    for _ in 0..SUBSTEPS {
        *p = rk4_step(lorenz, *p, h);
    }
}

Quick start

Running in two commands.

You need stable Rust and a GPU with OpenGL 3.3. Windows and macOS need nothing else. On Linux, install the ALSA headers first: sudo apt install libasound2-dev pkg-config.

01Run the demos

The first build compiles the whole engine and takes a few minutes. Use --release; the demos simulate tens of thousands of particles a frame.

shell
git clone https://github.com/Mattbusel/proof-engine.git
cd proof-engine
cargo run --release --example sky
cargo run --release --example lorenz

02Use it as a library

5,000 points start on one short line and follow the Lorenz equations. Also in the repo as examples/quickstart.rs.

shell
cargo new lorenz-demo && cd lorenz-demo
cargo add proof-engine
src/main.rs
use proof_engine::math::attractors::rk4_step;
use proof_engine::prelude::*;
use proof_engine::render::ui_layer::UiParticle;

fn main() {
    let mut engine = ProofEngine::new(EngineConfig::default());

    // 5,000 points in a line 2 units long, each 0.0004 from the next.
    let mut points: Vec<Vec3> = (0..5000)
        .map(|i| Vec3::new(1.0 + i as f32 * 4e-4, 1.0, 1.0))
        .collect();

    engine.run_ui(move |engine, dt| {
        // Advance every point along the Lorenz equations.
        for p in points.iter_mut() {
            *p = rk4_step(AttractorType::Lorenz, *p, dt);
        }
        // Draw them: x across, z up, centred in the window.
        let (w, h) = engine.render_size();
        let (cx, cy, s) = (w as f32 / 2.0, h as f32 / 2.0, h as f32 / 60.0);
        let color = Vec4::new(0.5, 1.2, 1.6, 1.0);
        let dots = points
            .iter()
            .map(|p| UiParticle::new(cx + p.x * s, cy - (p.z - 25.0) * s, 3.0, 3.0, '●', color))
            .collect();
        engine.ui.draw_particles(dots);
    });
}

cargo run --release. For about ten seconds the points travel as one streak; then chaos pulls them apart into the butterfly.

Four frames of the quickstart program at 1, 13.5, 16 and 18.5 seconds: a speck, a thin arc, loops splitting apart, and the full Lorenz butterfly.

FIG. 3BThat program, frames written by the engine at 1, 13.5, 16 and 18.5 seconds.

What is inside

Math first, then light.

math

Functions as animation

Attractors, Perlin noise, logistic map, Collatz, Lissajous, Mandelbrot escape, springs. Any glyph can carry a life_function that drives its position or colour.

math::fields

Composable force fields

Gravity, vortex, electromagnetic, strange attractor, shockwave, tidal, flow, dipole, with linear, inverse-square, exponential or Gaussian falloff.

entity

Particle-built bodies

Entities are glyph clusters held by force cohesion. Binding strength follows HP, so a hit knocks matter loose instead of playing an animation.

render

An HDR pipeline

Half-float scene buffers, a bloom pyramid, ACES, lens, light shafts, shadows from matter, grain and dither. Every standing parameter is a field on RenderConfig.

physics · audio

Simulation and sound

Rigid bodies with SAT, soft bodies, Eulerian fluid. 48 kHz synthesis with FM, filters, drive and reverb. Sound is synthesised, not sampled.

worldgen · scripting

Procedural everything

Tectonics, erosion, climate, rivers, settlements and history; Lotka-Volterra and SIR ecology; a bytecode VM with closures.

The screen pipeline: the 3D glyph pass and UI world pass draw into an HDR buffer, emission feeds a bloom pyramid, both meet in the composite, then FXAA, the screen, and the HUD painted sharp on top.

FIG. 4What runs on the GPU every frame. A game drawn as screen-space matter gets bloom, grade and grain on all of it, with a readable HUD over the top.

Demos

Twenty-one demos, one command each.

Every one is cargo run --release --example <name>. Close the window, or press Esc where the demo says so, to quit. These are the ones to start with.

galaxy3,000 glyphs, each on its own orbit.

strange_attractorsSeven chaotic systems, RK4, colour is speed.

math_rainColumn speeds from a sine, flicker from a logistic map.

Two particle-built fighters; the red one is coming apart after a hit

FIG. 5convergence: the red fighter has taken damage and its binding is failing.

The Proof Editor, an egui scene editor with a viewport, inspector and hierarchy

FIG. 6Proof Editor: place glyphs, fields and entities; save scenes as JSON.

ExampleWhat you see
skyA day over a mountain range, every sky cell a Nishita scattering integral. Space pauses, Up/Down change speed.
lorenz40,000 points on the Lorenz attractor, integrated with RK4 and drawn into the HDR world pass. Left/Right turn the view.
galaxyAbout 3,000 glyphs on four spiral arms, each on its own orbit, with a hot core and drifting nebula dust.
strange_attractorsLorenz, Rossler, Chen, Halvorsen, Aizawa, Thomas and Dadras side by side, 1,500 points each. Space pauses.
math_rainDigital rain of mathematical symbols; speeds from a sine, flicker from a logistic map.
quickstartThe program above: 5,000 points that chaos tears apart into the Lorenz butterfly.
convergenceTwo particle-built fighters in an arena with an orbiting camera; hits knock matter loose.
supernovaA star pulses, collapses, explodes and settles into a Lorenz nebula.
hello_glyphThe smallest program: one breathing @ and a gravity field.
colossusGPU density entities: millions of particles from sixteen bones. Needs a strong GPU.
apotheosisA character built on signed distance fields, about 10.8 million particles. Needs OpenGL 4.3.

Capture

Record the engine’s own frames.

Any program built on Proof Engine can write its own frames, read straight back off the GPU after post-processing, with no code changes. PROOF_HIDDEN=1 keeps the window invisible and unfocused, so it runs while you use the machine.

Every demo frame and video on this page was written this way.

shell
PROOF_HIDDEN=1 PROOF_FIXED_DT=60 \
PROOF_SHOT='frames/f_{n}.bmp' PROOF_SHOT_AT=560 \
PROOF_SHOT_EVERY=2 PROOF_SHOT_COUNT=240 \
cargo run --release --example sky

PROOF_FIXED_DT steps the simulation at a fixed rate, so a sequence plays back at true speed however long each frame took to capture. PROOF_WINDOW=1920x1080 sets the size.