OCEAN WAVES

The quest for a perfect set of waves has led me to experiment with several different types of wave generators. Here is a gallery showing some of the more interesting variations. While we have found methods that create very realistic physical waves, that kind of detail is not needed in a flight simulation. Once in the air, the waves can be seen only by their shading. And with many of the common methods (such as three.js ocean) the waves become invisible, especially when looking straight down. And while reducing the size of the wave plane increases resolution, this also tends to create "tiling" problems, which happens where the same texture is repeated several times within the field of view. We have still not found an optimal method which has good resolution and avoids tiling.

Textures

The simplest approach is to use flat planes with tileable textures and normal maps. This works well enough for waves at a distance. However, up close, there is no sense of motion.

Animated Textures

The three.js Ocean uses animated textures to create the illusion of waves. However, you quickly notice that there are no physical waves - the plane remains flat. SeanWasere has addressed this problem by adding waves to the Ocean program. Here are some examples:

In the last example, I need to determine the frequency and angle of the physical waves to pitch and bank the ship properly.

Unfortunately, the three.js Ocean texture does not lend itself to a flight simulation because, as altitude increases, a lot of detail is lost in the mirror textures.

Perlin Noise

You can create physical waves using a random noise generator. With care, you can create variations that are tileable and that use a single geometry and texture. We have not tried this method yet, so we have no examples to share.

Simple Sine Waves

You can create physical waves by using a flat plane with several segments. We used the following sine function to compute the y-value of each point in the plane:

y = (2*WavAmp*Math.pow(0.5*(Math.sin(time)+1),WvGrK1))-WavAmp;

Where WavAmp is the amplitude of the particular wave.

The results of each wave were added to the results from prior waves, creating a composite of waves. As long as the waves begin and end within the same plane, the results are tileable and you can create adjacent planes using the same geometry and texture.

We tried adding a fixed normal map to create the appearance of smaller waves and to increase visibility. We also tried either adding a texture map or making the wave color vary with height. With the assistance of prisoner849, we were able to add a custom shader extension to three.js materials, instead of haivng to create a new shader texture.

Here is a simple CodePen example that uses this method.

iFFT Waves

I next explored using the inverse Fast Fourier Transform (iFFT) method which can quickly generate hundreds of waves. I found an old three.js iFFT wave generator online which was created by Jeremy Bouny in 2016, and based on the work of David Li and Aleksandr Albert. Here are some examples (including some with a Pirate ship to give a sense of scale). Because the wave heights and frequencies are random, we still have to create a special routine to pitch and bank the ship properly.

Here is a simple CodePen example that uses this method and contains the revised iFFT wave generator.