18 - Water

Introduction

Before diving into the water simulation (haha, puns are fun) it is usually best to do some research and planning first, since there is a lot of theory involved in a nice looking water simulation and there are many ways you can tackle the problem. Having a clear design and direction in mind is key to making good progress, rather than going round and round in circles. It's hard to explain how, but I personally like to visualize what I want the water to look and feel in my mind's eye before starting any programming. Knowing beforehand how you want your water to look and feel helps with the technical side of things too, since you can mold your technical solution towards a specific goal you have in mind for certain problems.

That probably isn't the best explanation so I will try to explain the actual steps that I went through before making my water simulation:

    1. Before starting my water simulation, I had a couple of clear design goals in mind:
      1. Firstly I wanted my water simulation to look and operate a lot better than the current water simulation in popular voxel engines. (Namely Minecraft)
      2. I also wanted my water simulation to tackle a few more advanced water properties that other games don't handle at all. i.e water pressure and viscosity.
      3. And lastly I wanted my water to look great! Obviously choosing a voxel rendering style limits you options for this somewhat, but I wanted my water to look unique.
    2. I next tried to visualize how I wanted my water to look during rendering.
      1. Early on I came up with the idea that during water 'flow' (i.e. when water is in motion) I would make my water particles look different from just standard voxel blocks.
      2. When water was overflowing over the side of a block, I wanted it to look as if it was sliding down the side of the edge, rather than just appear in the adjacent space.
      3. Also when placing water, or when water was falling vertically, I wanted it to look like actual drops of water. Again, instead of just a 'block' of water falling down.
    3. After this, I thought about specific water problems (see below) and thought about how I could tackle them, and asked myself an important question for each complex water problem: "Do I want to solve this issue in my water simulation?"
    4. That question is actually very important, since you can eliminate a lot of headaches for yourself, if you just decide you don't want a certain water properties in your engine... Not interested in simulating correct water pressure? Then don't... simple!
    5. Finally, I drafted out some simple technical sides to the water simulation. What classes I would use, how my water would be created and managed, what sort of discrete simulation would I use, how could I interact with it using the GUI and interface, etc...
    6. Time to start coding!

Some great theory articles to read first before doing any programming:

Another good way to visualize how you wold like your water to look and feel is to take note of how other people have tackled the problem. If you can see what your 'competition' is doing, not only does this give you a great quality bar to set for yourself, but it will also give you great insight into how others have tackled the problem before you, Here is some information on other water simulation produced for other games:

These lists are by no means extensive, and just by doing simple Google searches for "Water Simulation" you get tons of resources and stuff to read. In fact I would recommend you spend at least a couple of days reading and gathering resources, jotting down designs and useful notes BEFORE doing even one line of coding.

The rest of this article is going to be dedicated to showing how I personally tackled water in my voxel engine and the way my water simulation works. I am in no way saying this is the best approach or even that I do certain things correct, I just found certain things that work well for me and fit into my voxel engine nicely.

Demonstration

Here is a video demonstrating my water simulation:

My Technical Solution

Water in my voxel engine is completely separate from the other voxel rendering. Doing it this way offers some advantages and also some disadvantages. The biggest disadvantage to separating the water away from my other voxel organisation and rendering is that I lose all the previous optimization and performance gains that other chunks and voxels have. I could have just made water a different 'block type' and handled it the same as all the other voxel types in my chunks. (This is how a lot of other voxel engines currently handle water).

Common Water Problems

Evaporation

...

U-Bend

...

Overflow

...

Combining Water

...

Pressure

...

Viscosity

..

Water Pumps/Generators

...