iFFT Wave Generator

I have been trying to find a good example of an iFFT (inverse fast fourier transform) wave generator written for three.js. One of the best examples is the FFT Wave generator written by Jeremy Bouny. However, this was written in 2016 and was only updated to r72. Here is a version of his program consolidated and updated to r101 using modules.

I decided to delete the mirroring effect since is makes the program run slower and is somewhat unrealistic (see photo at bottom of page) and I have updated the program to r150.

  • Here is the resulting program on CodePen.
  • Here is a copy on my webpage.

Because it is not an original program, but merely a consolidated upgraded extract, it retains whatever copyright protections were claimed with the original Jeremy Bouny program.

In addition to using the iFFT method to generate waves, the program illustrates how you can use a “buffer pipeline” to allow shaders to perform intermediate calculations. EDIT If you are interested in trying to figure out how the program uses buffers, there is an excellent discussion on this webpage. The webpage was written in 2016 and shows sample programs which contain many of the same instructions.

I hope this is helpful start for other programmers who are trying to add realistic looking waves to their programs.

This photo shows that even small waves are enough to prevent mirroring from being much of a factor:

EDIT - new
Here is a slightly modified version which includes mipmaps - to get rid of “rough” textures in distance - and that changes the color of the waves based on height. While the latter looks nice, it also highlights the amount of tiling. I have now also added back the shader instructions which reflect the sun.

MORE - 3.20.23
Here is a CodePen example (a work in process) where I am trying to modify the program so that you can use it to extend a regular 3JS texture. At the same time, I am trying to show what is happening in all the buffers, although the first 3 appear INOP for now. The normal map may not be correct yet. The normal map in the original program was not a stand-alone normal map, so I am having to make revisions.

UPDATE - 3.25.23
I have updated the CodePen example to show my latest efforts. To show how well the planes fit together, the nearest waves are displayed on 4 adjacent planes. These nearest planes are MeshStandardMaterial with added Displacement and Normal Maps. To illustrate how they look in the distance, I have added a more distant plane that is 4X larger with only the Normal Map added. While the planes do not match up 100%, it demonstrates that the planes match up visually.

One important feature of this particular (Li-Albert-Bouny) wave generator is that it includes a shader routine that you can use to create an animated Normal Map. I had to make some modifications to generate a standard Normal Map.

Here is a version added to my flying demo. The segments have been reduced to 128 and the plane size is 2 miles - which is enough to prevent tiling. I have added a temporary 512 texture to increase resolution.

And here is a version working with my more detailed flight simulation, still running at 60 fps. I should be able to improve the waves further by using a larger texture and by creating “animation” by putting different textures in different planes and switching their positions with each frame change.


Thanks for the efforts of migrating the code to the latest Three.js. There are many gems out there that are stuck to old releases.


Definitely, I started porting an old demo too (from an early threejs contributor in 2012) which I found really well made: demo

But the gap is quite big with current three version. It was using some feat called deferred renderer that have been removed since then…

I will see if I can manage to finish the port… currently I have an halfway version, and one fully migrated to latest three, but with degraded graphics.


I have added a reference to an article about using shader buffers that was written about the same time as the JBouny program. It shows that people were doing some pretty amazing things back then… Unfortunately, Google is horrible at finding these gems - it took me about a month to find the right combination of search terms to find these kinds of articles.

1 Like

Were you able to find a copy of the deferred renderer? The WebGLDeferredRenderer was apparently available through version r112.1: See: js version. and jsm version.