• Advertisement

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

The tangent vector is (equation 11)

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

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

Edited by iamyoukou

#### Share this post

##### Share on other sites
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.

#### Share this 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

##### 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

##### 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

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

Np

## 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

• Advertisement