This is a physically-based simulation of water flows across a 3-D landscape. The water surface is modelled as a 2-D heightfield using the "shallow water equations". The calculations are done on the GPU and the simulation runs in real time for reasonable grid sizes.

The intention of this work was to investigate the feasibility of using the shallow water equations within the context of physics simulation in videogames. Therefore, emphasis has been placed on computational efficiency and the graphical quality of the results, and not so much on strict physical accuracy.

Click here to download the demo zip file (2.1 M)

The demo runs on the Windows platform. Note that the demo requires DirectX 10.0 level graphics hardware.

The source code (2.3 M) is also available.

- Unzip the file then double click "shallow_water.exe".
- Use WASD keys and PageUp/PageDown to move the camera. (Hold Shift to move faster.)
- Right-click and drag to rotate the camera.
- Left-clicking will add water to the simulation. You can select other actions using the "Left_Mouse_Action" dropdown (on the right-hand side).
- Clicking the buttons under "Presets" (at the top right) will select different "scenarios". You can also play with various settings on the other tabs (these are described in detail in the Settings Guide).

The basic idea is behind the shallow water equations is that we take a vertical average of the equations of fluid dynamics (the Navier-Stokes equations). This leads to a new set of equations which describe the fluid depth and velocity as functions of x and y (the horizontal directions) only.

The advantage of doing this is that the computational cost of solving the equations is reduced (compared to a full 3-D simulation). The flip side is that the results are less realistic, since a 2-D "height field" approach (which is essentially what this is) fundamentally cannot represent certain features, such as breaking waves, complex splash/spray patterns, etc.

The equations themselves are well known and can be found in Acheson (1990) or on Wikipedia for example.

We use the method of Kurganov and Petrova (2007) to solve the equations. The calculation is done on the GPU in three passes (per simulation timestep) using custom pixel shaders (implemented in HLSL). It runs in real time for reasonable mesh sizes.

The rendering has deliberately been kept fairly basic at the moment. The water and terrain are rendered as simple height field meshes. The water shader takes into account attenuation (deeper water appears darker), reflection (but only the sky and clouds are reflected, not the terrain), refraction (in an approximate way), and the Fresnel effect.

This project illustrates that the shallow water equations can be used to good effect to simulate the motion of water across a landscape.

However, there are still improvements that could be made, and lessons that could be learned from the experience, as follows:

This work used the Kurganov-Petrova method, which is highly accurate and stable, but also rather computationally intensive. For games, we would probably want to use something faster.

In fact, after completing this project, I found out about the so-called "pipe flow" model (O'Brien and Hodgins 1995), which can be thought of as an approximation to the shallow water equations. This approximation is much faster to compute, although we do lose a certain amount of accuracy in the process. However, the results apparently look realistic enough for use in interactive graphics applications (if not engineering simulations perhaps!).

Therefore, an interesting piece of future work would be to implement the pipe flow model and compare its speed and accuracy with the Kurganov-Petrova model.

Although the graphics in my demo are reasonable, I think there is still room for improvement.

For example, consider the water graphics in modern PC games, such as this screenshot from *Skyrim*:

Comparing this to my own demo, I can't help but feel that the water in *Skyrim* looks better. Of course, we might say that they are "cheating," by using hand-painted textures and so on, while my project is trying to use physically-based simulation. However, it does illustrate that there is room for improvement in my demo.

Looking at the *Skyrim* screenshot, we can see that the artists have included lots of high frequency details, including small turbulent wave features, glints of light from specular reflections, and so on. These make the water look more "interesting" and more realistic.

Physically speaking, these details come about because of the shape of the water surface. A real water surface, especially in fast-flowing regions, is not completely "smooth," but has lots of short-wavelength perturbations resulting from turbulent motion, "ripples" caused by wind, and so on.

This suggests that perhaps we should be running our simulation at much higher resolution (in order to capture all those short-wavelength details) and then shading the water based on that simulation. However, if we crank up the resolution too far, we run into the limitations of the shallow water model, which isn't able to capture short-wavelength details very realistically (it works best when the wavelength is long compared to the water depth). Therefore, if you *really* want a realistic-looking water surface (and you want it to come from a physical simulation), you probably have to run a full 3-D simulation, which is not really feasible in real time on current hardware (although perhaps it's not far off, given how fast graphics hardware is improving!).

I suppose there might be ways around this – for example, one might consider inventing a simplified model to capture short-wavelength disturbances and then somehow overlaying this on top of the more complex shallow water model. In other words, we would be using one model to capture the fine details (to make the water "look nice") and another model to simulate the bulk motion of the fluid. I haven't tried to implement this, so I don't know whether it's feasible or not, but it might be an interesting direction for future work.

Here are some other improvements that could be made:

- Currently, the simulation is run over every grid cell, whether it contains water or not. Ideally, we would detect areas that contain no water and then avoid running the simulation on those areas. (This would be important if we wanted to have a large area of terrain with only small areas of water within it.)
- The HLSL code I've written could be better optimized.
- The rendering the code is rather primitive at the moment: it just blasts out a huge triangle grid to represent the heightfield, with no attempts at LOD or adaptive tesselation or anything like that.
- There are some rendering artifacts; most notably, a "diamond" pattern sometimes appears in areas where there is a sudden change in water depth. These should be investigated and fixed if possible.
- We could investigate imposing maximum speed and/or maximum depth limits on the simulation (high speeds or depths are a problem because they require shorter time steps to be taken for stability).
- The friction model used in the simulation is completely ad hoc and unrealistic. A better friction model should probably be implemented.
- The boundary conditions might be improved (in particular, the "inflow" condition is a big hack at the moment).
- Adding particle effects to simulate "splashing" might be interesting.

D. J. Acheson, "Elementary Fluid Dynamics", Oxford University Press, 1990.

A. Kurganov and G. Petrova, "A Second-Order Well-Balanced Positivity Preserving Central-Upwind Scheme for the Saint-Venant System", Commun. Math. Sci., Vol. 5, No. 1, pp. 133-160, 2007. Available online at https://projecteuclid.org/journals/communications-in-mathematical-sciences/volume-5/issue-1/A-Second-Order-Well-Balanced-Positivity-Preserving-Central-Upwind-Scheme/cms/1175797625.full.

J. F. O'Brien and J. K. Hodgins, "Dynamic Simulation of Splashing Fluids". In Proceedings of Computer Animation 95, pages 198-205, April 1995. Available online at http://graphics.berkeley.edu/papers/Obrien-DSS-1995-04/Obrien-DSS-1995-04.pdf.

The source for the "grass" texture used in the demo is the Terrain Texture Pack created by Virtually Infinite Systems (unfortunately no longer available online it seems).

The skybox texture was created using Terragen (classic edition, non-commercial licence).

The Guichan open source library was used to create the sliders and other GUI elements visible in the demo.

The above article includes a screenshot from *The Elder Scrolls V: Skyrim* which is published by, and copyright of, Bethesda Softworks.

The copyright in the shallow water demo itself belongs to the author (Stephen Thompson).