Expand description

A fast, chunk-friendly implementation of Naive Surface Nets on regular grids.

Mesh Examples

Surface Nets is an algorithm for extracting an isosurface mesh from a signed distance field sampled on a regular grid. It is nearly the same as Dual Contouring, but instead of using hermite (derivative) data to estimate surface points, Surface Nets will do a simpler form of interpolation (average) between points where the isosurface crosses voxel cube edges.

Benchmarks show that surface_nets generates about 20 million triangles per second on a single core of a 2.5 GHz Intel Core i7. This implementation achieves high performance by using small lookup tables and SIMD acceleration provided by glam when doing 3D floating point vector math. (Users are not required to use glam types in any API signatures.) To run the benchmarks yourself, cd bench/ && cargo bench.

High-quality surface normals are estimated by:

  1. calculating SDF derivatives using central differencing
  2. using bilinear interpolation of SDF derivatives along voxel cube edges

When working with sparse data sets, surface_nets can generate meshes for array chunks that fit together seamlessly. This works because faces are not generated on the positive boundaries of a chunk. One must only apply a translation of the mesh into proper world coordinates for the given chunk.

Example Code

use fast_surface_nets::ndshape::{ConstShape, ConstShape3u32};
use fast_surface_nets::{surface_nets, SurfaceNetsBuffer};

// A 16^3 chunk with 1-voxel boundary padding.
type ChunkShape = ConstShape3u32<18, 18, 18>;

// This chunk will cover just a single octant of a sphere SDF (radius 15).
let mut sdf = [1.0; ChunkShape::USIZE];
for i in 0u32..ChunkShape::SIZE {
    let [x, y, z] = ChunkShape::delinearize(i);
    sdf[i as usize] = ((x * x + y * y + z * z) as f32).sqrt() - 15.0;

let mut buffer = SurfaceNetsBuffer::default();
surface_nets(&sdf, &ChunkShape {}, [0; 3], [17; 3], &mut buffer);

// Some triangles were generated.


pub use glam;
pub use ndshape;


The output buffers used by surface_nets. These buffers can be reused to avoid reallocating memory.


This stride of the SDF array did not produce a vertex.



The Naive Surface Nets smooth voxel meshing algorithm.