Underwater World
Infinite explorable underwater world created using Rust and WGPU using marching cubes and 3D perlin noise populated with 3D boids.
- Running live on the web at: https://lelserslasers.itch.io/underwater-world
- Showcase video: https://www.youtube.com/watch?v=heCIgXLkNO0

Controls
- Change pitch: WASD or arrow keys
- Roll: Q/E or pgUp/pgDown
- Speed up: space
- Slow down: control
- Reset submarine: R or enter
Features
The main build target was WASM and WebGL, meaning I did not have access to any parallelism/threading or compute shaders. This made performance a key concern, especially with the generation of the world/chunks and the fish.
- Performance optimizations
- Chunks/World
- Each chunk is built one at a time and is split over multiple frames to keep the frame rate high
- To hide the chunk generation, the chunks to build are sorted:
- If they are in the view frustum
- If they are in the direction that the sub is facing
- Distance to sub but with a little extra prio to chunks with a lower Z value (because they are more likely to be not blank)
- After collecting the perlin noise values for a chunk, if the chunk will be blank, it skips trying to create the mesh and it will skipped for rendering
- Built chunk models are stored and sent to the GPU in a more compact way using index buffers
- Despite the fact that chunks take up 16x16x16 voxels, they are built out of 12x12x12 voxels
- When trying to render the chunks, it will only sent chunks that in the view frustum to the GPU
- vertex order is designed for backface culling
- Boids
- Index buffer + backface culling for models
- Spatial partitioning used to find boids that are close to each other instead of iterating through all boids
- If boids get too far from a point, they are teleported to the opposite side
- Chunks/World
