# Gerstner/Sinusoidal wave directional rotation (flow) in regards to ocean currents/trade winds

I'm trying to create an ocean simulation using Gerstner waves based on the GPU Gems: Effective Water Simulation from Physical Models. So far I've completed the directional wave functionality and currently want to expand it with an ocean current/trade wind system to drive the global wave direction. I'm having trouble understanding how to create flow of a single directional wave based on a sampled flow field.

Current wind is generated by deriving a flow field from Perlin noise:

float2 dir=float2(cos(2Pi * noise(x,y),sin(2Pi * noise(x,y));

When I input this vector into wave direction(D), the wave breaks at time 0 and direction of the wave doesn't match the flow field vector direction at location (x,y).

I'm using Perlin noise for a flow field as a quick and easy testing tool to get wave rotation in place. How the flow field will be generated for end project purposes is irrelevant right now.

The Gerstner function I'm using:

$$P(x,y,t)=\begin{pmatrix} x+\sum(Q_iA_i*D_i.x*cos(w_iD_i\cdot(x,y)+\varphi_it) ) \\y+\sum(Q_iA_i*D_i.y*cos(w_iD_i\cdot(x,y)+\varphi_it) ) \\\sum(A_isin(w_iD_i\cdot(x,y)+\varphi_it))) \end{pmatrix}$$

Would I be missing some variable like wave phase offset or some wave rotation rate? How is wave rotation calculated in regards of changing direction vector based on world position?

• Do you have a snippet of the code where you implemented the equations? Or, did it work before you tried using the noise for direction? Aug 14 '20 at 20:47
• I will quickly add that I don't think this is a very good way to compute direction. Two issues: 1) It's Perlin noise, which is visibly square biased. Try to use 2D simplex noise. 2) That isn't a true flow field, and has bias in which vectors can transition into which other vectors. In particular, the angle corresponding to the highest noise value, cannot rotate back to become the angle corresponding to the lowest noise value. Better to take a simplex or simplex-type implementation which supports derivatives, and rotate the derivatves 90 degrees like <-dy, dx>, then normalize them. Aug 14 '20 at 20:47
• For the above, github.com/KdotJPG/OpenSimplex2/blob/master/glsl/… isn't the fastest because it's 3D, but it should work. github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl could be modified to output gradients if you feel up to it. You can use github.com/ashima/webgl-noise/blob/master/src/noise3Dgrad.glsl as a reference, but I would use bccNoise4Point.glsl over noise3Dgrad.glsl if you want 3D, since bccNoise4Point.glsl is a more open implementation. Aug 14 '20 at 20:48