Skip to content
Wumpf edited this page Mar 2, 2015 · 23 revisions

Some experiments with realtime water simulation on heightfield terrains, using OpenGL 4.3.

Technology, How stuff works

Basics

  • C++11 (using mainly Visual Studio 2013)
  • OpenGL 4.3

Dependencies

  • ezEngine (File IO, Memory Management, Basic Math, Window creation, Input, ...)
    • A while ago I took a minor part in its development
  • GLEW (OpenGL function wrangler)
  • AntTweakBar (DropIn solution for tweak variables)
  • stb_image (For simplistic texture loading)

Simulation

  • The most of the sources were already GPU orientated, but almost none of them used the features of modern hardware. I rearranged nearly everything and make very often use of Compute Shader, Indirect Draw and other modern features.
  • Simulation in fixed timesteps - each frame the simulation steps n times, number of steps per second is constant.
  • Much FP32 :( - everything else limits the simulation or makes it explode

Water Simulation

Heightfield water: "Column base Water simulation" Water in column, each column connected to 4 neighbors with "virtual pipes". Outgoing flow in each of the 4 directions is saved per heightfield-pixel.

Idea relatively good explained and why the outgoing-flow thing is so important can be found here. While being not very detailed Theses slides can give a very good overview what this is all about.

  • Outgoing flow RGBA32F
  • Two passes atm: Compute outgoing flow, Apply flow
  • Output flow map on the fly in second pass (RG16f)

Rendering General

  • Simple Forward renderer
  • Gamma correct Rendering - it is really simple, try it if you haven't already!
  • The definite Fog ;)
  • One directional light atm

Terrain Rendering

  • Texture Blending
  • Fresnel is great everywhere!
  • Screenspace Tesselation inspired by this. Solved crack problem with triangle patches instead, no fine displacement map as described in the paper. Uses instancing, only 3 draw calls (one per Patch - full, one transition, two transitions)

Water Rendering

  • Reuses grid from terrain. Almost the same geometry setup, but cull patches under terrain in Control shader
  • tossed informations mainly from this article and from this thread around until I something came out I was confident with
  • Flow from flowmap
  • Some Foam for fast water (also influenced by flow map)
  • ScreenSpace Reflections
    • since the water has arbitrary slopes and levels!
    • accelerated with a custom "MaxMap" for faster raytracing

Sky Rendering

Athmospheric scattering, rendered into a fairly low res cubemap (doesn't really need many pixels!). Since I honestly didn't want to spend much time on this complicated topic, I use an existing implementation described by Florian Boesch here and did some adjustments to fit my needs.

Postprocessing

Filmic Tonemapping with simple Luminance adaptation.

Notes on Code

  • Using some fancy C++11 feature
  • Renderer is based on some gl wrapper classes that are not meant to abstract OpenGL but just to make things easier

Todo/Planned Features

(List not complete, mostly a memory aid to my self)

Handling

  • Add/Remove water with mouse Update: Possible now, but also happens when doing sth. in the TweakBar which is terribly annoying

Rendering

  • Better grid topology (mediocre atm when it comes to water intersection & popping reduction)
  • Compute Irradiance Spherical Harmonic from Skybox to light water and terrain
  • Better fine waves (since simulation has its limits...) - simple but confusing normalmap atm
  • Grass
  • Culling
  • Other Vegetation?
  • Clouds
  • Rain
  • Deferred MSAA sounds like a good idea

Simulation

Misc

  • Moar sliders - make more stuff tweakable, still many magic numbers in code
  • Less sliders - make parameters more interdependant, compute stuff; make things tweakable the EASY way
  • Good default values
  • More OpenGL wrapper stuff - especially these Samplers are annoying!
  • Better specification of dependencies to ezEngine ** Should only use major releases