Skip to content

Riverbed Developer Wiki

Téo Orthlieb edited this page Sep 14, 2024 · 4 revisions

Code Overview

Rendering

Riverbed is rasterized, as opposed to raytraced which is common in voxel games. This means that meshes are built for each chunks on the CPU and sent to the GPU.

Riverbed uses a Level Of Detail (LOD) technique to render faraway chunks at a lower resolution. The technique is very simple for now, skipping 1 every 2, 4, 8, 16 or 32 blocks depending on the chunk distance.

This video provides an excellent overview of the other rendering optimisations we use (or will implement soon):
https://www.youtube.com/watch?v=40JzyaOYJeY

Data representation

The voxel blocks are stored in a Bevy Resource, as a HashMap (actually Dashmap for concurrency) of 62^3 sized* chunks, each chunk stored as a flattened array with palette compression (cf: packed-uints crate).

Note: Chunks are of size 62^3 because they are also padded with neighboring blocks for meshing purposes, making them 64^3 in storage.
See https://github.com/Inspirateur/binary-greedy-meshing

Game loop

Riverbed has a regular Bevy game loop with inputs, movement, collisions etc. + 2 separate threads for meshing and generation. Decoupling meshing and generation is essential to make new terrain display at an acceptable speed, which is even more important in big render distances.

The whole process to render a new chunk goes something like this:

  • an ordered queue of what needs to be generated based on player position is maintained by the LoadOrders struct (in /gen/load_orders.rs)
  • this queue is shared with the generation thread that processes it as fast as possible, generating whole columns
  • the newly generated chunks (and any chunks modified by the player) are marked as "changed" in the block storing structure
  • the meshing thread fetches the closest "changed" chunks and meshes them with the appropriate LOD
  • another system mark chunks as "changed" when they get closer/farther from the player and need to change LOD
    (this is kind of a hack but does the job for now)

With this setup both the generation and meshing are always done on the closest chunks from the player which is necessary to keep up with the player when they're travelling at high speeds.

Clone this wiki locally