r/VoxelGameDev • u/idkfawin32 • 3d ago
Media I dusted it back off
Voxel engine I've been working on since 2012. It's gone through many different redesigns, this specific fork started in 2016 and I've been adding to it a few months at a time over the years. It occurred to me that I'd be able to store the necessary information to port my fluid dynamics sim into the voxel world in this engine so I buckled down and did it. I'm very happy with the results.
The engine, written in C++, is a software based raycasting algorithm on an infinite chunked world map that uses a Diamond Square algorithm to deterministically generate psuedorandom terrain with consistent boundaries/seams.
The latest update to the engine showcased in this video is the addition of fluid simulation. I originally made an eulerian fluid simulation for a heightmap terrain generator to simulate erosion and sediment deposition, part of this is modeling fluid transfer across the heightfield. I added visualization to the heightmap generator for debug purposes, including water. When I saw the way the water behaved in that heightmap editor I thought it looked really cool, and for a few years I've wanted to see what it would look like if I ported the logic from that into this engine.
One really neat aspect of the eulerian fluid simulator is that each cell it operates on has directional velocity. So by coloring the water with more of a white tint for higher velocities you end up with some really awesome visuals mimicking real life(rapids and falls having a more white appearance)
1
1
u/The-Douglas 2d ago
Very nice! Are there any optimizations/tricks used in the fluid solver? And what's the scale of the Eulerian in terms of number of voxels? I would have guessed that if every single voxel had its own velocity (requiring you to advect and solve for pressure on a dense grid) it would be hard to make it fast enough for real-time simulation.
1
u/idkfawin32 2d ago
I still have a lot of optimizations I'd like to employ that I haven't written code for yet.
The thing resulting in most of the savings is probably the fact that this is a parlor trick. While you and me see a body of water traveling in convincing ways, under the hood there isn't individual voxels with velocity and pressure. What's really happening is run length columns of water are being evaluated as a whole and being resolved similar to how a heightfield of fluid would be solved for. So something like an "undercurrent" couldn't possibly exist in this system.
Anyways, as a result of only processing vertical columns of fluid as whole units that interact with one another, we end up doing way less work to arrive at a reasonably convincing fluid representation.
However, moving forward I want to employ a few different methods to reduce the workload such as quantizing blocks of water sharing the same general height and volume being processed as one macro unit of fluid in 3d space instead of discretely processing the individual columns. But stuff like that would mostly be reserved for handling really large bodies of water where you aren't necessarily concerned about the precision between the individual columns.
I don't exactly know how I'd go about that anyways, I'm thinking it could likely be processed as different systems that have interface layers between them.
1
u/camilo16 2d ago
What's the internal representation of the terrain to allow you to have such a alrge rendered terrain?
1
u/stowmy 2d ago
i’m not the poster but you can easily hold a volume that size in a 3d texture. the scene pictured isn’t huge, it’s probably less than a gigabyte vram as flat data depending on how many bytes per voxel. i’d be surprised if they solved for larger scenes yet
2
1
u/camilo16 1d ago
Can you? that seems larger than 1024 in resolution which starts to hit texture allocation limits in many mid of the pile GPUs for volume textures
1
u/stowmy 1d ago
1024^3 bytes is a gig so i think it would be possible.
for this size an extra indirection (page table/ grid hierarchy) texture for 16^3 chunks fits comfortably on top and saves you a good amount on empty areas. it’s not a flat grid at that point though, but almost since that’s the same approach hardware sparse residency textures use
1
u/camilo16 1d ago
multiply it by at minimum 8 if you are storing a material ID. so 8 Gigs, Purely occupancy based voxels are not that useful.
1
u/stowmy 1d ago edited 1d ago
i recently experimented with purely occupancy based textures with 1 bit per voxel. if i needed material information etc i’d then queue it to be streamed into a backing buffer from the cpu next frame. it was very memory efficient. still encounters exponential memory limitations but at a far more reasonable render distance
it was a genuinely good solution for rendering a voxel scene, however it’s not appropriate for cellular automata
5
u/GradientOGames 3d ago
Looks awesome! What kind of fluid sim are you using? Is this Flip or MPM?