Jump to content
  • Advertisement
Andr

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 this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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 this post


Link to post
Share on other sites

Your using 

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 this post


Link to post
Share on other sites
3 hours ago, Scouting Ninja said:

Your using 

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 this post


Link to post
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.

 

Share this post


Link to post
Share on other sites

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

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!