No description
  • Rust 83%
  • Slang 17%
Find a file
Flexhd41 7f7c1ed64c Trace in camera-relative coordinates to fix far-from-origin stalls
Flying ~1.7 km from the world origin produced a vertical band of dark
streaks and nearly doubled GPU time (16.3 -> 28.4 ms). The step-count
debug view showed that band saturating the traversal step limit: rays
were not advancing at all.

exitT computed a cell face as (face - rayOrigin) * invRd from absolute
world coordinates. At 1.7 km an f32 has ~1.2e-4 m of resolution left, so
subtracting two large nearly-equal coordinates loses most of it, and a
near-axis-aligned ray multiplies the residual by a huge 1/rd. The
computed step fell below the rounding error and the walk stalled.

Traversal now runs entirely in camera-relative space. Level corners are
supplied as camera-relative offsets computed in f64 on the CPU, brick
indices are resolved within a level from small coordinates, and wrapping
is done on integer global brick coordinates so it stays exact at any
distance from the origin.

At the same position: 28.4 -> 17.8 ms with the artifacts gone. 10 km out
renders clean at 16.9 ms, and behaviour at the origin is unchanged.
Reproduced with zero edits, which ruled out the editing system.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 20:13:08 +02:00
crates Trace in camera-relative coordinates to fix far-from-origin stalls 2026-07-28 20:13:08 +02:00
shaders Trace in camera-relative coordinates to fix far-from-origin stalls 2026-07-28 20:13:08 +02:00
.DS_Store Trace in camera-relative coordinates to fix far-from-origin stalls 2026-07-28 20:13:08 +02:00
.gitignore Voxel engine: toroidal clipmap, path-traced lighting, streaming, editing 2026-07-27 21:30:37 +02:00
Cargo.lock Voxel engine: toroidal clipmap, path-traced lighting, streaming, editing 2026-07-27 21:30:37 +02:00
Cargo.toml Voxel engine: toroidal clipmap, path-traced lighting, streaming, editing 2026-07-27 21:30:37 +02:00
README.md Trace in camera-relative coordinates to fix far-from-origin stalls 2026-07-28 20:13:08 +02:00

Overrun

A high-performance voxel engine with path-traced PBR lighting, built around two bets: 6.25 cm voxels in an unbounded streamed world, and simulation — every voxel carrying material state so fire, heat, liquids and structural collapse are first-class rather than cosmetic.

Rust + wgpu, shaders in Slang. Targets Metal on Apple silicon, portable to Vulkan/DX12.

Status: engine work. You can walk around, dig, build, and stream an infinite world at 60 fps. The simulation layer is not written yet.

Requirements

  • Rust 1.97+
  • Slang shader compilerslangc must be on PATH, or set SLANGC to its location. Shaders are compiled to WGSL at build time, so this is a hard build dependency.

Running

cargo run --release -p ovr-client

The traversal benchmark from the initial feasibility spike still builds and runs, and is the reference for renderer performance numbers:

cargo run --release -p ovr-spike

Controls

WASD move
Space / Ctrl up / down (fly), jump (walk)
Shift boost
G toggle fly / walk
Left mouse dig
Right mouse place
Scroll brush size
14 material
F3 debug overlay
Tab cycle view: shaded / clipmap level / normals / step heatmap
L limit clipmap levels traversed
F toggle shadows
R cycle internal resolution
Esc release mouse

Editing any shaders/*.slang while the client is running recompiles and swaps pipelines live. A failed compile is logged and the previous pipelines stay bound.

OVR_* environment variables (OVR_POS, OVR_YAW, OVR_PITCH, OVR_MODE, OVR_LEVELS, OVR_SHADOWS, OVR_WALK, OVR_AUTOWALK) set startup state, so a specific view can be reproduced without touching the keyboard.

Layout

crates/
  ovr-voxel     brick/clipmap data model, palette compression, edits
  ovr-worldgen  terrain generation + background streaming workers
  ovr-render    wgpu renderer, GPU timing, shader hot reload, debug overlay
  ovr-client    window, player, input
  ovr-spike     traversal benchmark
shaders/        Slang modules shared by every kernel

How it works

Voxel data. A voxel is 1/16 m. Bricks are 8³ voxels carrying a 512-bit occupancy mask plus a palette-compressed payload; a coarse grid sits above them at 8³ bricks. Bricks are encoded as 0 empty, 1 fully solid (no payload at all), n+2 sparse pool slot. That singleton encoding is what makes terrain affordable — on heightfield terrain only ~1% of bricks need a pool slot, so a 256 m view radius spanning 4.3 billion virtual voxels fits in ~60 MB.

Clipmap. Four nested levels, each 2× coarser and covering 2× the distance, so cost is linear in level count rather than cubic in view distance. Brick coordinates are anchored to the world and wrap into the index texture modulo the level size, so moving a level costs a regenerated shell rather than a rebuild. Shells are generated on worker threads, and a level's origin is not moved until every brick is back — moving it early aliases new world coordinates onto stale texture contents.

Traversal. A four-level walk: clipmap level → coarse block → brick → voxel bitmask. Rays are split into segments at the nested box boundaries and each segment is walked at the finest level that actually contains it. Walking innermost-first is only correct for rays starting at the clipmap centre, which no shadow or secondary ray does.

Traversal runs entirely in camera-relative coordinates, with wrapping done on integer global brick coordinates. This is required, not an optimisation: in world space, finding a cell face means subtracting two large nearly-equal floats, and at 1.7 km an f32 has ~0.1 mm of resolution left. Multiplied by a near-axis-aligned ray's huge 1/rd, the step error exceeds the cell size, the walk stops advancing, and rays grind to the step limit in a visible band.

Lighting. Two rays per pixel — a primary and one shadow ray with a bias scaled to the hit voxel's size. Indirect light is deliberately not traced per pixel: measurement showed an incoherent bounce costs ~25 ms/frame at 1080p even capped to 1 m, so it will come from a world-space irradiance probe cache instead.

License

MIT OR Apache-2.0