Skip to ContentSkip to Navigation
Society/business Center for Information Technology Research and Innovation Support Virtual Reality and Visualisation

Water shader

Harbor of Groningen Seaports
Simulation of Groningen Seaports


For a real-time visualization of one of the Dutch harbors we needed a realistic water surface. The old water shader showed the same waves everywhere, but inside a harbor waves have many different directions and sizes. To solve this problem we needed a shader capable of visualizing flow. We developed a new algorithm called Tiled Directional Flow which has several advantages over other implementations.

Left 4 Dead 2, image from Siggraph 2010, Valve
Left 4 Dead 2, image from Siggraph 2010, Valve

After trying something different first, we got inspired by the Siggraph 2010 presentation Water Flow in Left 4 Dead 2 by Alex Vlachos from Valve. His approach was using a second normalmap and slowly go from one map to the other, by changing a blendfactor over time. At the point a map becomes invisible, he resets the sliding texture coordinates, so the animation can start from the beginning. A disadvantage is that it only works for non-directional wave patterns. If you looked at a still from the animation, you couldn’t see in which direction the waves are travelling. Another disadvantage is that the changing blendfactor introduces a visible pulsing behaviour. Vlachos did hide that, by introducing noise

Final result of watershader
Final result of watershader

Our Approach

Our contribution is a new algorithm, implemented in a shader that generates overlapping tiles. We used a low resolution flow texture for local speed, direction and size of the waves. Within a tile, the speed, direction and size of the waves is constant, so there is no problem with animating the waves, as this can simply be implemented using a sliding normalmap. The end result is a very visually appealing animation that shows a strong correlation to the flow direction, even when the frame stops.

tiling of the water
tiling of the water

Using overlapping tiles, each point has a contribution of four normals. Adding the different normalmaps of each tile together results in nice animated waves, which don’t look like sliding normalmaps anymore. The contribution of each tiles goes slowly to zero near the edge of the tile. This would result in a visible effect, because the addition of many normalvectors together tends to create a more upright vector. In the shader this is prevented by assuming the waves behave like noise and by scaling the normal to compensate for this effect (adding N noise sources together, each with amplitude A creates a noise with an amplitude of sqrt(N)*A). To maximize the area where each tile adds to the animation of the waves, the contribution doesn’t go linear to zero, but with a third power. Note that the blendfactor doesn’t change over time and avoids the pulsating behaviour from Vlachos implementation.


  • flowing water
  • Pixel shader flow, not geometry
  • no visible repeating textures
  • directional waves
  • variable direction, speed, and length of waves

use low resolution ‘flow’ texture for:

  • local speed
  • local direction
  • local length
  • local transparency


  • per pixel direction, speed, length gives weird results


  • Water Flow in Left 4 Dead 2, Alex Vlachos, Valve, Siggraph 2010
  • use two normal textures which repeatedly blend in and out.
  • When not visible, reset texture coordinates.


  • waves are not directional. Using a normal map with directional waves, make them appear to move sideways
  • pulsing behavior (a bit hidden by using a noise texture to change the phase of the pulsing


  • do not vary the blending of the normal maps in time, but in space
  • assuming water behaves as noise, scale the result of adding normal with the expected amplitude
  • create on the fly tiling with per tile constant setting for speed, direction, length, so no reset of texture animation is needed
  • use overlapping tiles and blend them together to hide seams between the tiles


  • needs 4 tiles blended together, (more texture lookups compared to Valve’s water)

free advantage:

  • nice animated waves due to the blending of 4 different waves.
  • use non-linear blending to maximize the area of equally blended waves


  • add pseudo refraction


Video 'go with the flow' is  here

Video 'how to go with the flow' is here

Download the source code with images from here

Related Work

Last modified:16 January 2019 1.58 p.m.