Simulating water over terrain
lisyarus.github.io
lisyarus.github.io
Rendering Fluids: https://www.youtube.com/watch?v=kOkfC5fLfgE
I Tried Putting my Fluid Simulation on a Planet: https://www.youtube.com/watch?v=8nIB7e_eds4&t=817s
GitHub: https://github.com/SebLague/Fluid-Sim?tab=readme-ov-file
[0] https://www.youtube.com/playlist?list=PLFt_AvWsXl0dT82XMtKAT...
So although procedural generation is often a great case for parallelizing, one of the cases you’d most want parallelization for can’t really be parallelized on unbounded domains.
I haven’t seen a lot of exploration of this topic.
One of my favourite people on the internet working on this stuff is https://nickmcd.me — he’s got some of the best procedurally generated terrain I’ve seen.
But his work is also domain-constrained due to the simulation design.
I’ve thought about potential solutions and I think the best way would be to procedurally generate water shed boundaries that can’t be broken. Then you can parallelize and simulate an entire water shed at once.
It’s such an interesting problem, but it’s also way out of my knowledge domain so I’m mostly just an observer.
1) Have a small domain
2) Have a large resolution
3) Have a very long initial load time
Any of these suck for game development.
I always thought animal crossing had a clever and efficient approach to this without any terrain manipulation. You can chop a tree, and it'll dispense logs, but only so many before it essentially has a cooldown. You get the feedback and the finite resources, without expensive terrain manipulation.
Of course that doesn't work for every game, and really works better on smaller maps, but something worth considering. Terrain manipulation is pretty expensive, if your game doesn't need it it's probably better to do without (again, a generalisation)
It a standard strategy for resource dispensation (though cooldown doesn’t alleviate the infinite resource problem; it just slows it down), it’s just… boring and unimpactful
It's also cheap and easy. You have limited resources to work with in game dev, even more if you care about performance on anything but the most powerful machines. I'm of the opinion that those resources should be spared for what makes your game unique and fun.
In animal crossing of course, half the point of the game is to kill time peacefully, so it wouldn’t apply. With the game in question, the meaningfulness is unknown
This brought back memories of implementing my own GPU-based fluid dynamics in 2011 for my thesis. It was also for fluid (blood) across a surface (tissue) and was simulated in 2D but projected across the mesh with considerations for gravity and surface inclination. Even put a short video of it on YouTube: https://youtu.be/4vGrNc-GGW8
I was experimenting with a similar idea recently with the help of o3-mini-high. I talked it through my idea for an algorithm, and it implemented and rendered it in 3D with no manual intervention (although I did prompt it a number of times):
https://3d-water-sim.netlify.app/
It's not perfect yet because I stopped playing with it, but it was improving significantly with each iteration.
Fun fact, it implemented a working version of perlin noise correctly from scratch instead of pulling it from a CDN or something as part of this, for the terrain generation.
It’s a journey versus destination question.
I guess that can be solved averaging he value of a flow arrow with the 6 neighbor arrows in the same direction. With a big weight with the arrows that are in the front and back, and a small weight for the arrows that are on the sides. For example with these arrows
-a-> -b->
-c-> -d-> -e->
-f-> -g->
then New_d = d * (1 - 2*.1 - 4*.01) + (c+e)*.1 + (a+b+f+b)*.01
Where .1 and .01 are weight that I just invented but must be tweaked, perhaps with a power like the one they use to kill osculations. That coefficient can also be included: New_d = d * (1 - 2*.1 - 4*.01 - .001) + (c+e)*.1 + (a+b+f+b)*.01 New_d = d * (1 - 2*.1 - 4*.01) + (c+e)*.1 + (a+b+f+b)*.01
is as good as conserving momentum as the original model. (Assuming you calculate all the new values using a new matrix instead of overwriting the old ones.) It breaks energy conservation, but that simulates the friction between oposite direction currents, without going to the whorls level.I agree that this is not 100% realistic, but I think it's a good and simple addition to the model in the article, and tweaking the coefficients it may give a good enough visual result.
grid 0: water height in each cell
grid 1: water flow at each edge (first derivative)
grid 2: water acceleration in each cell (second derivative)
So each grid is the dual of the previous one and stores its derivative. In fact I don't think you even need to store edge data as a special case, just corner data and work purely with dual grids. You can derive the edge flow by taking the sum of the flow at the two corners of the edge. So you update the fluid height based on flow, then you update acceleration based on how much fluid mass flowed into the cell with what velocity, then you update the flow based on acceleration and current fluid height. I don't really know fluid dynamics, but looking at it purely from a numerical simulation standpoint, it sounds about right. It would also let you have diagonal flow.
I couldn't figure out erosion before this project moved to the cold shelf of personal project storage.. I liked how author mentioned this and attached the equations.
NOTE: you need to change the model values in the bottom toolbar to see big effects.
It is a cell-based simulation that uses WebGL to calculate cell values based on adjacent cells. The shader that does that is here:
https://github.com/concord-consortium/flooding-model/blob/ma...
That's Creeper World for you.
Also, the grid resolution required to obtain nice waves was a bit too much for the effort I put 5 years ago (probably needed another thread, etc.)
(ie letters being walls, background the floor)
In this setup one edge update affects two cells, so the cells are no longer trivially independent. It's still possible to update cells in parallel, but it requires splitting the update into two checkerboard-like passes.
See e.g. the classic exposition by Leveque:
https://www.clawpack.org/riemann_book/html/Shallow_water.htm...
Computational accuracy is not important to me at all.