Shawn Sagady
Shawn Sagady

Reputation: 31

Finding Height of Gerstner Wave at World Coordinate

Using the GPU Gems Article Effective Water Simulation From Physical Models I have implemented Gerstner Waves into UE4, I have built the function both on GPU for the tessellated mesh displacement and in code for the purpose of sampling height of the waves, but the issue I have run into is that the points by nature of the formula move away from their original points, so when using the gerstner function to get the height of a point, it is not necessarily at the point you are sampling so provides an incorrect height for that coordinate.

So somehow I need to solve for the point in the gerstner function that is actually lines up with the world position. I've taught myself enough to implement the waves, but i'm stuck on this solution, though I suspect there is some sort of matrix or way to take the inputs, apply the cos values and use it as a lookup for the actual point to sample. Any ideas and help is greatly appreciated.

For Reference the Gerstner Wave Formula

Formula Image

[2]

Q = Slope
 L = WaveLength
    A = Amplitude  
    D = Vector2 Direction  
    x = x world coordinate  
    y = y world coordinate  
    t = time  
    Where Qi = Q/wi * A * NumWaves  
    Where wi = 2pi/L  
    Where phase = Speed * 2/L

Upvotes: 3

Views: 1017

Answers (2)

user28052472
user28052472

Reputation: 1

Also late to the post: but i think the only way to solve this, is by some kind of aproximation. I implemented a working aproximation for gerstner waves using newtonian style gradient decent with 4 iterations:

Your problem, generally formulated, is:

Given a position a,b - what are the coordinates x,y, such that

P(x,y,t)=a,b,c

-> this will result in c being the local hight for coordintes a and b.

I dont think, there is an analytic inversion of P derivalble, instead one can solve the minimization problem (for fixed t)

F(x,y)= P(x,y) - a,b = 0

Wich can iteratively aproximated, for example with:

x_1,y_1= F(x_0,y_0)/|det(J(F)(x_0,y_0))| - (x_0,y_0)

where J(F)(x,y) is the jacobian of F (wich is easily derivalble from the Gerstner Function definition)

Upvotes: 0

rune
rune

Reputation: 101

6 years old, but i might as well answer If you have a simple 2d displacement function like:

gerstner wave displacement

where an input t produces an output x and y for a single wave

you can backtrack to an adjusted t value that produces an x,y pair where the output x is close to the original t, meaning the output y is a close approximation of the height at that t value

the x value of the result

pseudo code (in godots shader lang):

const int ITERATIONS = 4; // 3 or 4 is good enough for my uses
float steepness = 0.6;
float t = TIME;

float adjust_t = 0.0;
for (int i = 0; i < ITERATIONS; ++i) {
    adjust_t = -cos(t + adjust_t) * steepness;
}

// then compute the actual displacement with adjusted t value
vec2 displace = vec2(cos(t + adjust_t), sin(t + adjust_t)) * steepness;

(steepness goes from 0.0 to 1.0 and determines the sharpness of the peaks)

(i referenced this tutorial to make my gerstner wave function)

Upvotes: 0

Related Questions