How to compute normal vectors for gerstner waves

Started by
5 comments, last by ErnieDingo 7 years ago

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).

Advertisement
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.

Indie game developer - Game WIP

Strafe (Working Title) - Currently in need of another developer and modeler/graphic artist (professional & amateur's artists welcome)

Insane Software Facebook

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.

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 !

Indie game developer - Game WIP

Strafe (Working Title) - Currently in need of another developer and modeler/graphic artist (professional & amateur's artists welcome)

Insane Software Facebook

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;
}

Indie game developer - Game WIP

Strafe (Working Title) - Currently in need of another developer and modeler/graphic artist (professional & amateur's artists welcome)

Insane Software Facebook

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 :)

Np

Indie game developer - Game WIP

Strafe (Working Title) - Currently in need of another developer and modeler/graphic artist (professional & amateur's artists welcome)

Insane Software Facebook

This topic is closed to new replies.

Advertisement