The simplest way to create an ocean wave is to use a variation of the sine formula. However, creating a realistic display requires a lot of waves. But using the sine formula to compute all of these waves is slow. The iFFT (or Tessendorf) wave generator uses an inverse of the FFT (Fast Fourier Transform) method to quickly generate a lot of waves.
There are now several versions of this module, which are all available in the jsm directory of our GitHub repository.
The WebGPU versions include:
* Ocean4 | - | This works with r166 (and possibly earlier). |
* Ocean4a | - | This works with r167 and later. |
* Ocean4t | - | This works with r167 and later and uses a localTimer rather than an external timer. |
The WebGL2 version is:
* Ocean3 | - | This should work with r158 and later versions. |
Our initial challenge with creating this module was that we were unable to find a current example of a three.js iFFT wave generator. The best example we found was a three.js wave generator created in 2015 by Jérémy Bouny, based on a 2014 js version created by David Li which was adapted to three.js by Aleksandr Albert.
With the help of Attila Schroeder, we updated and revised that wave generator to create the Ocean3 (WebGL2) module. We combined all of the programs and shaders into a single program. We eliminated the portion of the program and the shaders used to create the final display. Instead, the program simply creates displacement and normal maps which you can use with standard three.js materials. We eliminated the program dealing with reflections since you can create reflections using three.js materials.
Attila Schroeder continued his efforts and created a comprehensive GPU module which is significantly improved. Ocean4 and variants are shortened versions of that module.
In a three.js program, you import all the three.js and other modules at the beginning of the program. You use this instruction to import the Ocean4t module:
import {Ocean} from "https://PhilCrowther.github.io/Aviation/jsm/Ocean4t.js";
The Ocean4t module uses the following variables to store data.
//- Grid Square Data let GrdSiz = 3200; // Smallest Grid Square (3200 meters = 2 miles) let GrdRes = 512; // Resolution let AnmSpd = 1; // The Animation Speed (can vary with GrdSiz) //- Constants let WndSpd = 20.0; // Wind Speed let WndHdg = 0.0; // Wind Heading let Choppy = 2.0; // Wave Choppiness //- Variables let waves = 0; // Where the Ocean module is stored let wav_ = { // Sources Res: GrdRes, // Resolution - segments per square (default = 512) Siz: GrdSiz, // Size of Smallest Square = default = 3200m = 2 miles WSp: WndSpd, // Wind Speed WHd: WndHdg, // Wind Heading Chp: Choppy, // default = 1 // Animated Maps Dsp: 0, // The Displacement Map Nrm: 0, // The Normal Map NMS: new THREE.Vector2(1,1), // Normal Map Scale (flip Y for left-handed maps) Spd: AnmSpd // The Animation Speed };
waves = new Ocean(renderer,wav_);
waves.update();
* wave |   | Simple 2x2 grid of animated waves [rev 240909] |
* fdem |   | Demo of generic jet flying over an animated ocean [rev 240909] |
* fmod |   | Model of an FM2 airplane flying over an animated ocean [rev 240909] |
* fsim |   | Model of an FM2 airplane in simulation with animated ocean [rev 240909] |
These programs can be found on our GitHub repository.
In this case:
The wav_ variable does not include the Spd variable.
The Initialization command is:
waves = new Ocean(renderer,wav_,WavTim);And the Animation command is:
waves.render(WavTim); // Note that this uses the term render, rather than update