This is something I played with two years ago - I posted it as a demo on gamedev.net forums (link) but later never had time to get back to it. My plan was to write a detailed article, but as it seems that will never happen and people frequently ask me for more info, I've decided to simply put it all up here with just a brief overview and full project source code.
The goal of this whole thing was to render realistic flowing water for big terrain areas on DirectX9 generation hardware.
The basic idea was to precalculate water flow over a static terrain represented by a heightfield and then use this data in the realtime application (game, simulation, etc) to do a simpler and cheaper localised wave simulation and rendering.
The process is thus split into two stages:
- Waterflow simulation (editor) stage
- Realtime 3D visualisation stage
The demo project contains both stages (modes), which can be toggled between using F5 key. See Readme.txt contained in the archive for more details.
Waterflow simulation (editor) stage
This is the 'editor' stage (it would go into a tools pipeline / editor in the case of a game engine): it takes a heightmap as input and, in my case, a list of springs which add water to the simulation. It outputs the state of the simulation - usually once it is stabilised. This simulation process can take tens of minutes or hours, based on the terrain size and other parameters. Once the user is happy with the way water is flowing across the terrain, it can save a 'snapshot' of the simulation state which exports it in a format used by the next, realtime renderer stage.
One good example of a similar algorithm that can be used for this, with more realistic simulation and terrain erosion, is described the "Interactive Terrain Modeling Using Hydraulic Erosion" (link). I am not going to explain my version as it is pretty similar, but feel free to dive into (pun not intended) source code and ask any questions.
Here is a short video of the algorithm in action:
Realtime 3D stage
The renderer stage will not further modify the base water flow, but will use simpler surface wave simulation and effects to provide the illusion of moving water. This is enough for most visualisation or game purposes and is fast and scalable.
A couple of effects are used to provide the appearance of moving water:
Simple localised surface wave simulation that affects normal map and displaces water vertices to a certain degree and can bounce from river banks or other objects. I think I based my algorithm on this article and with a little bit of tweaking made it work on the GPU. This simulation is then moved using the velocity map from the simulation stage to add the realistic water flow effect.
This simulation will only be performed on a rectangular block representing the area around the observer. When the observer moves, the simulation area is updated accordingly. Since this is a relatively fast simulation, newly added area will quickly stabilise into the regular wave pattern for the represented area, so few or no visible artifacts will be induced (unless observer moves too fast).
To allow for a distance based level of detail and add more wave frequencies, multiple simulation layers are run in a cascaded fashion, with each cascade covering the smaller one and its surroundings with the observer near the center.
Water perturbance is added to simulation cascades at real time based on the first stage (flow) simulation state, at areas of high velocity deltas. It will also be added for any other input such as wind or floating/splashing objects.
One additional channel in the simulation texture is used to store a quantity representing the amount of foam which is propagated in parallel with the simple wave simulation well using the velocity map from the flow simulation stage. This adds to the appearance of faster moving and/or splashing water areas.
The foam is rendered using foam tiled texture mapped using UVs that move along the velocity map direction. To prevent UV stretching (as the velocities are different on different areas), three overlapping layers (with slightly different UV scales and offsets) are continuously blended between in such way that the blending is always done between two textures while the third one is not visible and can have its UVs reset to prevent stretching. This is further augmented by a noise based blending mask to hide tiling details and hide blending artifacts.
Same (or very similar) technique for achieving flowing normal and colour maps was recently presented in SIGGRAPH 2010 Water Flow in Portal 2.
Finally, high frequency waves are added to areas of higher water velocity by simply adding animated normal 'noise' wave map on top using the same technique of moving UVs as for displaying the foam texture.
There you go! Of course, there are many things that can be improved and also two stages could be combined to add a completely simulated realtime flow effect. This would enable you to do something like the upcoming Ubisoft's 'From Dust' game, which looks amazing indeed!
The project with the full source code (DirectX9, C++, VisualStudio 2010) can be downloaded from here.
Just the binaries can be downloaded from here.
Datasets can be downloaded from:
hetch_half_dataset (lo-res - good for playing with simulator as it's quick)
hetch_full_dataset (hi-res - looks much better)
4k_x_2k_dataset (big one, pretty unfinished, I could've added more rivers)
If you wish to use your own heightmap, there's an explanation on how to set up a project in the readme file, and you'll need this to convert from a 16bit grayscale .tiff heightmap into .tbmp format used by RiverSim. Have fun and I'll be glad to answer any questions!
My paper, Continuous Distance-Dependent Level of Detail for Rendering Heightmaps, was recently published in the journal of graphics, gpu and game tools - it took a while but it's finally done.
Slightly updated version can be downloaded from here - demo, code and data download links are in the paper.
This paper presents a technique for GPU-based rendering of heightmap terrains, which is a refinement of several existing methods with some new ideas. It is similar to the terrain clipmap approaches [Tanner et al. 98, Losasso 04], as it draws the terrain directly from the source heightmap data. However, instead of using a set of regular nested grids, it is structured around a quadtree of regular grids, more similar to [Ulrich 02], which provides it with better level-of-detail distribution. The algorithm's main improvement over previous techniques is that the LOD function is the same across the whole rendered mesh and is based on the precise three-dimensional distance between the observer and the terrain. To accomplish this, a novel technique for handling transition between LOD levels is used, which gives smooth and accurate results. For these reasons the system is more predictable and reliable, with better screen-triangle distribution, cleaner transitions between levels, and no need for stitching meshes. This also simplifies integration with other LOD systems that are common in games and simulation applications. With regard to the performance, it remains favourable compared to similar GPU-based approaches and works on all graphics hardware supporting Shader Model 3.0 and above. Demo and complete source code is available online under a free software license.
I'm currently working on a DirectX11 CDLOD demo, and when that's done I'll try out what I wanted to play with for a while now - the hardware tessellation. We'll see how it goes; I'll post the results here.
Let me know if you find this paper (and code) useful and if you have any questions or suggestions!
 Adding the download links here... [\edit]
Binaries and a small example dataset
Complete source code
Since I haven't been updating the my terrain library (AdVantage Terrain - silly name, isn't it?) for a while now and I'm probably not about to do so in the future, I've decided to close the web page and move everything here.
But not all is lost! In the meantime I've been working on a paper that describes an updated/modified version of the algorithm that inherits the quadtree organisation, but works directly on heightmaps (kind of like 'Geometry Clipmaps', but with more correct LOD distribution and smoother transitions between levels) - I'll update this web page with all the details as soon as it gets published. The paper will come with the full free-to-use source code and everything, so it practically makes AdVantage terrain library obsolete except in some rare scenarios.