Blender Tutorial: Water

Intoduction

Last Saturday, the weather was quite good. So I decided to make a little tour on my bicycle. When I crossed the river Elbe, naturally I happened to look at the water. I stopped to observe the water for a while. Observation is the most important factor if you want to achieve a convincing look in your images. It's a simple logic: without knowing the world you cannot recreate it.

Water Characteristics

My observations of water on that Saturday and in other situations revealed the following characteristics:

  1. There are many different kinds of water. Its look depends on the type and size of the water body as well as its depth. It also depends on the environment and the weather, its clarity and much more. Consequently, there cannot be one CG representaion of water that works in every situation. In this tutorial we will mimic the water surface of a river or lake at mild wind.
  2. The surface contains waves of different sizes. If the water body is moving as in a river, the large waves only change shape but more or less stay in the same position, while the small waves show the movement down the river. However, if the water body is not moving but influenced by wind as in a lake, the large waves move more than the small ones. The crests and throughs of water waves are not uniform. In fact, the crests are usually tighter than the throughs.
  3. Water is transparent and reflective. The amount of reflected light depends on the viewing angle. If you look at right angle onto a water surface, you can see through. If you look at an acute angle, the surface acts like a mirror. All transparent materials show this behaviour.

Tutorial

Let's try to reproduce my observations and impressions in Blender to create convincing CG water. It is just a material test with no surroundings and definitely has to be adjusted in a complete scene.

In the default scene delete the cube, create a plane, increase its size to fill the camera view, go to the material buttons and choose the default material.

Waves

The first texture channel should already be filled with a dummy texture. If not, create one. Then switch to the texture buttons. Choose texture type 'Clouds' and increase the NoiseSize to 0.350, which gives a slighty better resolution, and select 'Hard noise'. The latter is important to make the crests tighter. It's not perfect but closer to real waves than uniform soft noise and the best way I discovered in Blender yet.

Back in the material buttons map the texture to Nor and move the Nor slider to an appropriate value. I used 0.8 here. So much for the large waves.

For the small waves, we put the same texture into the second channel and adjust its size in the Map Input panel to be about four times smaller, thus sizeX, sizeY and sizeZ have to be set to 4. Map it to Nor as well and move the Nor slider to 0.6, a bit less than the large waves. Make a test render. It look should similar to this:

Test Rendering 1

Reflection

To make the plane look like water we have to simulate the observed surface properties.

Clear water does not reflect light in a diffuse way. Therefore turn the Ref slider to zero. However, if you want the water look muddy, a brownish color and some diffuse reflection might be appropriate.

Now the specular reflection comes. To make it easily visible, move the lamp behind the plane. Choose the Blinn shader because it provides the possibility to create highlights with very sharp edges, just as highlights on a water surface look like. Spec 1.0, Hard 150 and Refr 10.0 proved to look good. Make another test render:

Test Render 2

All we need now is a reflection of the environment in the water. I used an existing environment map for this, because in our test scene there is no surrounding that could be reflected by raytracing. I used the following envmap which you may download now: beach_envmap.png (265 KB)

Add a new texture to the third texture channel and in the Texture context choose EnvMap. Select Load and press Load Image to get the envmap into Blender. Back in the Material context select Refl on the Map Input panel and map the texture to Cmir. Now the material is highly reflective over the whole surface like quicksilver.

To finalize the material and to change the look from quicksilver to water, three things need to be changed on the Mirror Transp panel. Turn on ZTransp to make the water transparent. Increase the Fresnel value to make the reflection depend on the viewing angle. Fresnel 3.3 is good for our purpose. Finally, move the SpecTra slider to 1.0 for nice opaque highlights.

Because the default blue background looks a bit cheesy here, let's change it to black in the World context before rendering the final still image:

Final Rendering

Animation

Animating this water in Blender is not difficult at all.

For both wave texture channels create keyframes for the texture offset by pressing I with the mouse cursor over the material buttons and selecting Ofs in the pop-up menu. Then go to frame 100. Change ofsZ to 0.6 for both texture channels and create keyframes again. The ofsZ value influences the shape of the waves without shifting them along the water plane which lies in the XY plane. Higher values lead to faster movement, lower values to slower movement.

In the IPO window switch to IPO type Material and change the Ofs IPO curves for both wave texture channels to linear interpolation for equal speed during the whole animation. The texture channels can be accessed through the number next to the IPO type field. Render the water animation from frame 1 to 100 and press Play to view it. Voila!

We didn't implement any sideway shifting of the waves yet. Let's do this now to improve the animation even more. Beside ofsZ, just animate ofsX and ofsY as well according to the observations described above. I made examples of a river and a lake:

Video:
Source:
river_divx.avi (1.4 MB)
river.blend (72 KB)
Video:
Source:
lake_divx.avi (1.3 MB)
lake.blend (72 KB)

I hoped you enjoyed this tutorial. Please experiment on this basis. There is always room for improvement. Good luck with your CG projects!

Roy Schulz
22.01.2005