Sign in to follow this  
iamyoukou

How to compute normal vectors for gerstner waves

Recommended Posts

I'm reading the article of ocean surface simulation based on gerstner waves in this book: http://http.developer.nvidia.com/GPUGems/gpugems_ch01.html

But I don't understand how to compute the normal vectors (equation 10 ~ 12).

Currently, I got

[attachment=35446:question_0.png]

It seems that the article makes the following assumption

[attachment=35447:question_1.png]

But how is that possible?

Or did I miss something?

 

=================================

edited, 2017.03.28, 08:30

=================================

The bi normal vector is (equation 10)

013equ02.jpg

The tangent vector is (equation 11)

013equ03.jpg

The normal vector given by the article is (equation 12)

013equ04.jpg

I don't understand how they cancel out those summation terms (e.g. part 1a and part 1b).

Edited by iamyoukou

Share this post


Link to post
Share on other sites
If i remember you need to calculate tangent and bi normal and then you can cross prod to get the normal. I have that formulas in hlsl code right now. Will dig up the code and send later today but someone might beat me to the punch and post.

Share this post


Link to post
Share on other sites

If i remember you need to calculate tangent and bi normal and then you can cross prod to get the normal. I have that formulas in hlsl code right now. Will dig up the code and send later today but someone might beat me to the punch and post.

The equations for calculating tangent and bi normal vector are (10) and (11).

The article also gives a result of the cross prod you mentioned (equation 12), but it doesn't show the whole calculating steps. And I don't understand some part of those missing steps :(

By the way, sorry for not showing equation (10) ~ (12), I will edit my post.

Share this post


Link to post
Share on other sites

 

If i remember you need to calculate tangent and bi normal and then you can cross prod to get the normal. I have that formulas in hlsl code right now. Will dig up the code and send later today but someone might beat me to the punch and post.

The equations for calculating tangent and bi normal vector are (10) and (11).

The article also gives a result of the cross prod you mentioned (equation 12), but it doesn't show the whole calculating steps. And I don't understand some part of those missing steps :(

By the way, sorry for not showing equation (10) ~ (12), I will edit my post.

 

Don't worry! :)  Will post the code tonight !

Share this post


Link to post
Share on other sites

This is the code I have been using...

void GerstnerWaveTessendorf(float aTime, float waveLength, float speed, float amplitude, float steepness, float2 direction, in float3 position, inout float3 result, inout float3 normal, inout float3 tangent, inout float3 bitangent)
{
  //  float L = waveLength; // wave crest to crest length in metres
 //   float A = amplitude; // amplitude - wave height (crest to trough)
    float k = 2.0 * 3.1416 / waveLength; // wave length
    float kA = k * amplitude;
    float2 D = normalize(direction); // normalized direction
    float2 K = D * k; // wave vector and magnitude (direction)
    

    // peak/crest steepness high means steeper, but too much 
    // can cause the wave to become inside out at the top
  //  float Q = steepness; //max(steepness, 0.1); 

    // Original formula, however is more difficult to control speed
    //float w = sqrt(9.82*k); // frequency (speed)
    //float wt = w*Time;
    
    float S = speed * 0.5; // Speed 1 =~ 2m/s so halve first
    float w = S * k; // Phase/frequency
    float wT = w * aTime;

    // Unoptimized:
    // float2 xz = position.xz - K/k*Q*A*sin(dot(K,position.xz)- wT);
    // float y = A*cos(dot(K,position.xz)- wT);

    // Calculate once instead of 4 times
    float KPwT = dot(K, position.xz) - wT;
    float S0 = sin(KPwT);
    float C0 = cos(KPwT);

    // Calculate the vertex offset along the X and Z axes
    float2 xz = position.xz - D * steepness * amplitude * S0;
    // Calculate the vertex offset along the Y (up/down) axis
    float y = amplitude * C0;

    // Calculate the tangent/bitangent/normal
    // Bitangent
    float3 B = float3(
        1 - (steepness * D.x * D.x * kA * C0),
        D.x * kA * S0,
        -(steepness * D.x * D.y * kA * C0));
    // Tangent
    float3 T = float3(
        -(steepness * D.x * D.y * kA * C0),
        D.y * kA * S0,
        1 - (steepness * D.y * D.y * kA * C0)
        );

    B = normalize(B);
    T = normalize(T);
    float3 N = cross(T, B);

    // Append the results
    result.xz += xz;
    result.y += y;
    normal += N;
 
	tangent += T;
    bitangent += B;
}

Share this post


Link to post
Share on other sites

 

This is the code I have been using...

void GerstnerWaveTessendorf(float aTime, float waveLength, float speed, float amplitude, float steepness, float2 direction, in float3 position, inout float3 result, inout float3 normal, inout float3 tangent, inout float3 bitangent)
{
  //  float L = waveLength; // wave crest to crest length in metres
 //   float A = amplitude; // amplitude - wave height (crest to trough)
    float k = 2.0 * 3.1416 / waveLength; // wave length
    float kA = k * amplitude;
    float2 D = normalize(direction); // normalized direction
    float2 K = D * k; // wave vector and magnitude (direction)
    

    // peak/crest steepness high means steeper, but too much 
    // can cause the wave to become inside out at the top
  //  float Q = steepness; //max(steepness, 0.1); 

    // Original formula, however is more difficult to control speed
    //float w = sqrt(9.82*k); // frequency (speed)
    //float wt = w*Time;
    
    float S = speed * 0.5; // Speed 1 =~ 2m/s so halve first
    float w = S * k; // Phase/frequency
    float wT = w * aTime;

    // Unoptimized:
    // float2 xz = position.xz - K/k*Q*A*sin(dot(K,position.xz)- wT);
    // float y = A*cos(dot(K,position.xz)- wT);

    // Calculate once instead of 4 times
    float KPwT = dot(K, position.xz) - wT;
    float S0 = sin(KPwT);
    float C0 = cos(KPwT);

    // Calculate the vertex offset along the X and Z axes
    float2 xz = position.xz - D * steepness * amplitude * S0;
    // Calculate the vertex offset along the Y (up/down) axis
    float y = amplitude * C0;

    // Calculate the tangent/bitangent/normal
    // Bitangent
    float3 B = float3(
        1 - (steepness * D.x * D.x * kA * C0),
        D.x * kA * S0,
        -(steepness * D.x * D.y * kA * C0));
    // Tangent
    float3 T = float3(
        -(steepness * D.x * D.y * kA * C0),
        D.y * kA * S0,
        1 - (steepness * D.y * D.y * kA * C0)
        );

    B = normalize(B);
    T = normalize(T);
    float3 N = cross(T, B);

    // Append the results
    result.xz += xz;
    result.y += y;
    normal += N;
 
	tangent += T;
    bitangent += B;
}

Thank you for the code : )

I think 

N = cross(T, B)

in your code is more reasonable than the equation (12) in that article.

Thanks again  :)

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