# Liquid flow over heightmap

I’ve been in search for code example (in language that i can actually understand C / C#) of an algorithm which allows me to “flood” heightmap with liquid (water) step by step.

All i have found so far are bits and pieces but nothing solid.

So the situtation is that ihave array of heights (float) Hmap[x,y] and i want to make simple simulation of water flowing over this heightmap. I am also hoping to get a read on somesort of “displacement” power how much water is travelling over certain point in the map for use of other functions i might add (maybe erosion or something).

Any tips or straight algorithms that deal with this? (and yes i’ve googled it around, but i am not sure if i got the proper technical keywords)

marching cubes?

Ha ha. Good one!

There is no simple solution for this. Simulating incompressible fluids is really, really hard. Simulating compressible ones is only slightly easier.

So, yeah, of course it can be done, but expect to spend a few months digging deeply into very technical papers (or hiring someone to do it for you).

I guess the simplest I can think of is probably to model your fluid as a bunch of little spheres. Drop 'em on the terrain and let the physics engine roll them around. This will be a decent approximation of fluid behavior, though of course it won’t look anything like fluid. To solve that, you could hide them, and compute a mesh around wherever they are (perhaps using marching cubes, as @jister suggested).

Also known as MetaBalls:
http://wiki.unity3d.com/index.php?title=MetaBalls

I have never tried this script nor do I know if it’s good, just giving you something to google.

1 Like

Liquid simulations are complex. I mean really, really complex. I spent several years studying fluid dynamics at University. And yet I am still struggling to build a basic believable simulation from scratch in Unity. Of course I’m trying to incorporate rain and evaporation, which are likely not needed for your approach.

There are two basic approaches to fluid simulations.

• Grid simulation. This basically involves building an array that holds data on every position. Fluid movement is calculated by calculating the movement of fluid into and out of every cell.
• Particle simulation. Fluid is broken up into a bunch of particles. Each particle has physics applied.

Both techniques then require a rendering step to convert the concentrations into an actual surface.

Depending on exactly what you are looking for, you can also get away with just simulating the water surface. This can be much easier, but much less accurate.

So given all of that, I would suggest a grid based approach. Use a 2D grid. Set each cell to be the height of the water. To figure out flows, compare the height of the water + terrain to the height of the water + terrain in all the surrounding cells.

This is exactly what i was thinking. The water does not need to exist on… break waves. Just 2d flow. I had the algorithm that did this years written in C and it worked like a charm. I dont need “realistic” waterflow. Just need the grid stuff to do some simple erosion calculation.

In that case the algorithm becomes very simple. In psuedo code

float [,] waterHeight; // Needs to be buffered, not shown here
float [,] heightMap;
float diffusionFactor; // Anything above about 0.2 will give an unstable simulation.

void DoFlowTick (){
for (int x = 0; x < waterHeight.GetLength(0); x++){
for (int y = 0; y < waterHeight.GetLength(0); y++){
float heightDifference = TotalHieght(x-1, y) - TotalHeight(x, y);
if (heightDifference > 0) {
float waterLevel = waterHeight [x-1, y];
waterHeight [x, y] += heightDifference * waterLevel * diffusionFactor;
waterHeight [x-1 ,y] -= heightDifference * waterLevel * diffusionFactor;
}
// And so on in all the cardinal directions.
}
}
}

float TotalHeight (int x, int y){
return waterHeight[x,y] + heightMap[x,y];
}

This was written on the fly, expect bugs.

In practice I find I get a more stable simulation with a double buffer system. You’ll also need to deal with the viscosity artefacts that this simulation brings if your tick time is too small. You will also get ‘square flow’ and diagonal artefacts if your cell size is too small. You’ll also need to deal with bounds checking and the like.

Like I said, fluid simulations can get complex. And there are a thousand edge cases that will crop up. But they are certainly fun.

3 Likes