#meshing #voxel #greedy #binary #chunk #voxel-game

binary-greedy-meshing

A port of https://github.com/cgerikj/binary-greedy-meshing to Rust

14 releases

0.3.5 Aug 28, 2024
0.3.4 Aug 22, 2024
0.2.0 Aug 21, 2024
0.1.6 Aug 15, 2024

#321 in Data structures

Download history 75/week @ 2024-07-26 161/week @ 2024-08-02 349/week @ 2024-08-09 652/week @ 2024-08-16 344/week @ 2024-08-23 26/week @ 2024-08-30

1,376 downloads per month

MIT license

36KB
317 lines

binary-greedy-meshing

Originally a port of Binary Greedy Meshing v2 to Rust, with additional improvements such as support for transparent blocks.

How to use

This crate is used in the Bevy voxel game Riverbed, you can check out the code for usage examples.

Minimal example

use binary_greedy_meshing as bgm;
use std::collections::BTreeSet;

fn main() {
    let mut voxels = [0; bgm::CS_P3];
    // Add 2 voxels at position 0;0;0 and 0;1;0
    voxels[bgm::pad_linearize(0, 0, 0)] = 1;
    voxels[bgm::pad_linearize(0, 1, 0)] = 1;
    // Contain useful buffers that can be cached and cleared 
    // with mesh_data.clear() to avoid re-allocation
    let mut mesh_data = bgm::MeshData::new();
    // Fill the opacity mask, this can be cached 
    for (i, voxel) in voxels.iter().enumerate() {
        // If the voxel is transparent we skip it
        if *voxel == 0 {
            continue;
        }
        let (r, q) = (i/bgm::CS_P, i%bgm::CS_P);
        mesh_data.opaque_mask[r] |= 1 << q;
    }
    // Does the meshing, mesh_data.quads is the output
    bgm::mesh(&voxels, &mut mesh_data, BTreeSet::default());
}

What to do with mesh_data.quads

mesh_data.quads is a [Vec<u64>; 6], 1 Vec per face type, each u64 encoding all the information of a quad in the following manner:

(v_type << 32) | (h << 24) | (w << 18) | (z << 12) | (y << 6) | x

The face groups correspond to Up, Down, Right, Left, Front, Back, in this order. (assuming right handed Y up)

The fastest way of rendering quads is using instancing (check this video to learn more about the topic), but if it's not available you can still convert the quads to vertices and indices making a regular mesh, see this Riverbed files for an example of this:

Performance

Benching the crate on Intel(R) Xeon(R) CPU E5-1650 v3 @ 3.50GHz:

  • meshing (with transparency support): 600μs

This is coherent with the 50-200μs range (without transparency) reported from the original C version of the library, as transparency incurrs a significant cost in the hidden face culling phase.

The meshing is also ~7x faster than block-mesh-rs which took ~4.5ms to greedy mesh a chunk on my machine.

chunk sizes are 62^3 (64^3 with padding), this crate doesn't support other sizes.

No runtime deps