Ocean Waves
Ok, now for everyone's favorite shading excercise, water (oh boy!). The tough thing about water is that, if you're not careful (or don't like to pay attention to physics) your shader will end up looking like cloth or tar pits or mountains of ice cream. So, to avoid future embarrasment, here is a quick lesson on the physics of waves. First off, the most important thing to udnerstand is that waves do not actually move water. Waves are simlpy large masses of energy flowing through the water. They take on the shape of sin waves, similar to light or sound. Second, waves are simply a random assemblage of sin waves. Their amplitudes and frequencies are correlated and the general probability of amplitude decreases as amplitude increases. However, the direction of their travel at open sea is evenly distributed. Thus, we can easily create functions to create many many layers of sin waves and have the result appear to be ocean waves. If you try to manually place the waves, you will create somethign which looks gelatinous or static. Lastly, when waves cross, the total energy at that point is the sum of the individual waves.
Of course, near the shore, waves act differently. The following schematic illustrates their behaviors, but I havent had time to impliment these functions yet. Here, you can see the energy quality of waves, they dont actually move matter, just energy.


So, with this knowledge, we can create a fractional shader (similar to FBM) which creates layers of sin waves, with most of the waves having fairly low amplitude and high frequency. The pseudocode for this shader would appear something like this:
A = 1 F = 1 Phase = 0 totalHeight = 0 for i:= 1 to layers do begin rotateCoordinates(x) totalHeight := totalHeight + sin(x * F + Phase) * A A := A * 0.5 F := F * 2.0 Phase := Phase + PI / 6 endThe function rotateCoordinates simply rotates the s and t values by a random amount. To animate the waves, we simply describe a linear interpolation for totalHeight. Instead of beginning at 0, we could animated the value across frames. An accumulation of waves results which resembles complex ocean waves. To understand the summation of waves, the graphy below shows two overlapping waves and the third resultant wave. The irregular shapes of waves is due to the sub-waves being of slightly different wave lengths. This causes patterns known as interference which can appear to be random but are actually a comlpex, rythmic pattern.

Also, as the diagram points out, the combined movement of features is not directly dependent on the sub waves. This allows the waves to have that nice undulating appearance. Again, the trick is to allow all the waves to be random, rather than controlling them, which results in contrived appearances.
So, here is a test of the shader with a basic set of parameters. I made over two hundred tests of this shader over ten hours. While making wave patterns is not difficult, creating a particular look is time consuming. I wanted a billowing, deep ocean appearance.

So, with several days of testing, I eventually came up with the following pattern. With some careful lighting, we get the open see at late evening.

Richard Reed kindly provided me with a Shake macro to create sparkly sheen on the water's surface.
