Perturbations
The
water mesh is implemented as a flat polygonal mesh using the lefthand
coordinate system, where the Yaxis represents the up dimension and
the Zaxis points away from the viewer. This mesh is divided in n
slices in either dimension specified by the user. The figure below
shows the top view of the mesh as if it's been divided in three slices.
Sphere
mapping or refractive texture mapping is not too interesting over
a flat mesh, especially for simulating water. Taking this fact into
account, it's necessary to perturb the mesh.
There
are several ways of perturbing the mesh to look like water, some faster
and some slower. A very efficient way is by using the array approach
described by Hugo
Elias and Jeff Lander ("A Clean Start: Washing Away the Millennium,"
Game Developer, December 1999). However, the array approach only simulates
approximations of ripples on the mesh. If the application needs to
perturb the mesh with a constant directional wave, or a combination
of directional waves, the array approach cannot be used. Another method
is to use a spring model, modeling the flat surface as a set of two
dimensional springs, which can produce very realistic effects. Lastly,
we can simply use sums of sine or cosine functions which creates very
good results. For the sake of simplicity, the sample program explained
here implements perturbations using sums of sine wave functions.

Figure
4. Mesh divided in three slices, top view.

Sine
Waves
In
order to understand how the sample program perturbs the polygonal
mesh using sine wave sums, let's quickly review some properties of
sine wave functions.
In
2D space (X, Y) as function of X, sine waves can be written as:
y(x)
= a * sin(kx  p), where
x
= Xaxis value
y = Yaxis value
a = wave amplitude
k = wave number (frequency)
p = phase shift
(Equation 3)
The
amplitude (a) is how big the wave is because it multiplies the whole
function. The wave number (k) is related to the wave frequency: the
smaller this number is, the greater the frequency and vice versa.
The phase shift shifts the wave to either a positive or negative direction
of the Xaxis. In terms of animation, we can use the time as a phase
shift to make the waves move each frame.
In
3D space, the sine wave equation can be extended to (using the lefthand
coordinate system):
y(x,z)
= a * sin(k(xi + zj)  p) (Equation 4)
where
x = Xaxis value
y = Yaxis value (in this particular case, the height of the wave)
z = Zaxis value
a = wave amplitude
k = wave number (frequency)
p = phase shift
(i, j) = wave directional vector components
Equation
4 is a straightforward extension of Equation 3 for 3D space. The only
part that needs special attention is the wave directional vector components
(i, j). In this case, they define in which direction the wave is traveling
on the XZ plane. As an example, let's write the wave equation as if
the wave is traveling 45 degrees (p/4 radians) in respect to the Xaxis.

Figure
5. Top view of a wave traveling at 45 degrees.

If
we project the wave directional vector (unit vector) on the X and
Zaxis, by simple trigonometry the components can be computed as:
and
So
the equation for this example can be written like: