# OpenGL Trouble with Gerstner Waves Normals

## Recommended Posts

Hello all,

I have been implementing Gerstner Waves in my engine and i have encountered a problem that as kept me from moving on.
The positions are being computed correctly but the computed normals (using equation 12 in this paperhttps://developer.nvidia.com/gpugems/GPUGems/gpugems_ch01.html) do not seem to be correctly interpolating in the fragment shader.

Here is the code in the vertex shader:

// Normal
for(int i = 0; i < nGerstnerWaves; i++)
{
float WA = waveFrequency[i] * waveAmplitude[i];
float waveNormal = waveFrequency[i] * dot(waveDirection[i], totalPosition.xz) + (wavePhaseConstant[i] * timeStep);

totalNormal.x += waveDirection[i].x * WA * cos(waveNormal);
totalNormal.y += waveCrest[i] * WA * sin(waveNormal);
totalNormal.z += waveDirection[i].y * WA * cos(waveNormal);
}

totalNormal.x = -totalNormal.x;
totalNormal.y = 1 - totalNormal.y;
totalNormal.z = -totalNormal.z;

totalNormal = normalize(totalNormal);

And the Wave parameters are these (just one wave for now)

"amplitude": 1.5, "direction": [1.0, 0.0], "steepness": 0.8, "speed": 0.9, "length": 10.0}

In the fragment shader this normal is again normalized.

And heres two quick videos of the issue:

" rel="external">

" rel="external">

Thank you in advance, and anything else you need just ask

André

Edited by Andr

##### Share on other sites

I have added a geometry shader in between to draw each normal and each normal per face and this is what i got:

" rel="external">

As you can see some normals are being set to a negative value for a part of a wave cycle which should never happen, any ideas on why this is happening?

Thanks

##### Share on other sites

Sorry for the bump but i still havent figured out what am i doing wrong ... Any clues or possible debug methods for this?

Thank you,

André

##### Share on other sites

On 8/29/2017 at 9:41 PM, Andr said:

As you can see some normals are being set to a negative value for a part of a wave cycle which should never happen

Your using sin and cos waves. Both range from 1 to -1. So you should +1 to them to get 2 to 0. Then to get your results back to a range from 1 to 0 (For positive normals) you should devide by 2 or *0.5 to prevent the / by zero error.

So:

    totalNormal.x += waveDirection[i].x * WA * cos(waveNormal);
totalNormal.x = (totalNormal.x +1) * 0.5; //Corecting for positive results

totalNormal.y += waveCrest[i] * WA * sin(waveNormal);
totalNormal.y = (totalNormal.y +1) * 0.5;//Corecting for positive results

totalNormal.z += waveDirection[i].y * WA * cos(waveNormal);
totalNormal.z = (totalNormal.z +1) * 0.5;//Corecting for positive results
}

Of course in your video only one axis appears to be wrong, so maybe you only need to do it with that one axis.

Sorry I know my normal maths as a 3D modeler, I don't know much about shaders.

##### Share on other sites
3 hours ago, Scouting Ninja said:

Your using sin and cos waves. Both range from 1 to -1. So you should +1 to them to get 2 to 0. Then to get your results back to a range from 1 to 0 (For positive normals) you should devide by 2 or *0.5 to prevent the / by zero error.

So:


totalNormal.x += waveDirection[i].x * WA * cos(waveNormal);
totalNormal.x = (totalNormal.x +1) * 0.5; //Corecting for positive results

totalNormal.y += waveCrest[i] * WA * sin(waveNormal);
totalNormal.y = (totalNormal.y +1) * 0.5;//Corecting for positive results

totalNormal.z += waveDirection[i].y * WA * cos(waveNormal);
totalNormal.z = (totalNormal.z +1) * 0.5;//Corecting for positive results
}

Of course in your video only one axis appears to be wrong, so maybe you only need to do it with that one axis.

Sorry I know my normal maths as a 3D modeler, I don't know much about shaders.

HI!

Thank you for you reply! I should have though of that trick before, i used it many times before while converting between spaces in opengl!

Although it fixes the Y axis going negative, it cant be used for x and z components because we actually want them to oscillate between negative and positive values. The issue now is that, for example for the X component, it overshoots way too much which suggests a problem with the amplitude of this component as seen in this video:

" rel="external">

For a small wave the X component of the normal oscillates way more than it should (it should have a direction similar to the face normal)

Edited by Andr

##### Share on other sites
18 minutes ago, Andr said:

Although it fixes the Y axis going negative, it cant be used for x and z components because we actually want them to oscillate between negative and positive values.

Was expecting something like this. Good to know it helped.

19 minutes ago, Andr said:

For a small wave the X component of the normal oscillates way more than it should (it should have a direction similar to the face normal)

That is what your "Steepnes" value should effect. Because the larger the wave is the more it would oscillate, so a shallow wave should oscillate less.

So you could just multiply "Steepnes" with the X normal to reduce it's effect, or just multiply a new value with it to reduce the effect.

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

1. 1
Rutin
25
2. 2
3. 3
JoeJ
19
4. 4
5. 5

• 14
• 11
• 9
• 9
• 10
• ### Forum Statistics

• Total Topics
631754
• Total Posts
3002104
×