Advertisement

Trouble with Gerstner Waves Normals

Started by August 26, 2017 10:46 AM
5 comments, last by Scouting Ninja 7 years, 5 months ago

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é

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

Advertisement

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é

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.

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)

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.

 

This topic is closed to new replies.

Advertisement