Contact Home

2D Liquid Simulator With Cellular Automaton in Unity

Posted on: January 30th, 2017 by admin 5 Comments

Liquid Physics Using Cellular Automation

One interesting way to represent liquids in a grid based world, is to use a form of cellular automaton. You may have heard of cellular automata from the popular “Conway’s Game of Life”, where cells evolve based on a set of rules that they adhere to.

As the cells evolve, they create some interesting patterns, sometimes even chaotic in nature. For our liquid simulation, we are going to want to enforce some strict rules, so that we have much more control over the movement of our cells.

Take a look at the following gif. Notice how the liquids are all contained inside of grid cells. Each cell is capable of holding a value to indicate how much liquid is contained inside of it.

maq8M

In this simulation, the cells attempt to disperse their liquid into their neighboring cells. It will do this by following rules that we will set for them. In each iteration of our simulation, every cell that contains liquid will execute the same set of rules.


Rule #1: Flowing Into Bottom Neighboring Cell

First, a cell will check to see if it is capable of flowing downwards into its bottom neighbor. This makes sense as we want liquid to fall down as if it was affected by gravity.

The amount of liquid that is allowed to flow into another cell is calculated based on the amount of liquid already in the source and destination cells. Liquid will only flow if the destination cell has less liquid than the source cell.

Once we have calculated the amount of liquid to flow, we make the adjustment to the liquid value of both cells to reflect the change. The images below (from left to right) depict how the liquid behaves, showing one iteration of the simulation per image.

The liquid falls into the cell below in each iteration, until it is unable to fall any more:

A01 A02 A03


Rule #2: Flowing Into Left and Right Neighboring Cells

Once the cell has finished executing the first rule, it will then attempt to distribute its remaining liquid towards the left or right neighboring cells. Again, the amount of liquid that is allowed to flow is dependent on the current amount of liquid in each cell.

In the following images, you see that the liquid moves down during the first iteration. During the second iteration, it can no longer flow downwards, therefore it flows into the adjacent cell that is available to its right:

B01 B02 B03

If both neighboring left and right cells are available to accept liquid, then the cell will flow in both directions in the same iteration:

C01 C02 C03


Rule #3: Flowing Upwards with Pressure

After the cell has executed both Rule #1 and Rule #2, it will then verify if it still contains more liquid than the maximum amount allowed. If it does contain more liquid, then the cell becomes pressurized. A pressurized cell will be allowed to flow upwards if possible. This behavior is illustrated below:

G01 G02 G03 G04


Determining the Flow Direction of each Cell

As we iterate over each of our cells that contain liquid, and apply the above rules, we can also keep track of the last iterations flow direction for each of our cells. Doing so, will allow us to know in what direction each cell is flowing at all times.

flow


Rendering Falling Liquids

Liquids that are flowing downwards do not render very nicely, as they sometimes only contain a small amount of liquid in the cells. Rendering the amount of liquid directly in these cells can look somewhat strange:

E01 E02 E03 E04

If we add a check to see if the liquid flowing downwards, we can render these cells as having a full unit of liquid. This is mainly to make the simulation render a little nicer. Doing so, would render the liquids like this:

F01 F02 F03


Conclusion

Although this type of liquid simulation is a great for grid based solutions, in order for the liquid to be fluid, it requires a high iteration rate on each frame. By increasing the iteration count, you can adjust the speed at which the liquid moves making it much more realistic, at the expense of more CPU cycles per frame.

// Run our liquid simulation 
for (int n = 0; n < Iterations; n++)
    LiquidSimulator.Simulate (ref Cells);

Finding a balance that works for you will be an important step to take when implementing a system like this.


Try the Demo

Check out the WebGL demo here.

Left Click to place/remove walls. Right click to place liquid.

Liquid Simulator Demo


Source Code

Source code has been published on Github:

https://github.com/jongallant/LiquidSimulator




References:
http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/

5 Responses

monty commented on January 31, 2017 at 1:05 am

it would be cool if you could simulate negative pressure as well so that you could create suction/siphoning

Torsten Grust commented on February 3, 2017 at 11:53 pm

Thanks for a nice writeup. This will make for a nice challenge/exercise for my students.

I was thinking that one could simply use character-based graphics (Unicode symbols) to render the final fluid simulation. Looking at your Unity prototype, all that would be needed are the characters

▁▂▃▄▅▆▇█

it appears (we’d miss the instructive arrows that indicate flow direction, though).

Keep up the great work,
—Torsten

Kunyu Wang commented on January 31, 2019 at 10:02 am

Could you explain the function CalculateVerticalFlowValue in LiquidSimulator.cs? I don’t understand these lines of codes:
if (sum <= MaxValue)
value = MaxValue;
why value=MaxValue even if there the liquid amount is less than MaxValue?
I read the blog in the references and there is not a clear explanation in there too.

And thanks this writing is really helpful.

Respond

Leave a Reply

You must be logged in to post a comment.