Skip to content

Instantly share code, notes, and snippets.

@yorung
Last active December 13, 2023 07:09
Show Gist options
  • Save yorung/5f72b5bff2082cd15f1722cd2f679dfa to your computer and use it in GitHub Desktop.
Save yorung/5f72b5bff2082cd15f1722cd2f679dfa to your computer and use it in GitHub Desktop.
Calculate gerstner wave normal, binormal, and tangent by GPU Gems's method.
float3 CalcGerstnerWaveNormal(float3 P)
{
float3 normal = float3(0, 1, 0);
[unroll]
for (int i = 0; i < numWaves; i++)
{
Wave wave = waves[i];
float wi = 2 / wave.waveLength;
float WA = wi * wave.amplitude;
float phi = speed * wi;
float rad = wi * dot(wave.dir, P.xz) + phi * g_time;
float Qi = steepness / (wave.amplitude * wi * numWaves);
normal.xz -= wave.dir * WA * cos(rad);
normal.y -= Qi * WA * sin(rad);
}
return normalize(normal);
}
float3 CalcGerstnerWaveBinormal(float3 P)
{
float3 binormal = float3(1, 0, 0);
[unroll]
for (int i = 0; i < numWaves; i++)
{
Wave wave = waves[i];
float wi = 2 / wave.waveLength;
float WA = wi * wave.amplitude;
float phi = speed * wi;
float rad = wi * dot(wave.dir, P.xz) + phi * g_time;
float Qi = steepness / (wave.amplitude * wi * numWaves);
binormal.x -= Qi * wave.dir.x * wave.dir.x * WA * sin(rad);
binormal.z -= Qi * wave.dir.x * wave.dir.y * WA * sin(rad);
binormal.y += wave.dir.x * WA * cos(rad);
}
return normalize(binormal);
}
float3 CalcGerstnerWaveTangent(float3 P)
{
float3 tangent = float3(0, 0, 1);
[unroll]
for (int i = 0; i < numWaves; i++)
{
Wave wave = waves[i];
float wi = 2 / wave.waveLength;
float WA = wi * wave.amplitude;
float phi = speed * wi;
float rad = wi * dot(wave.dir, P.xz) + phi * g_time;
float Qi = steepness / (wave.amplitude * wi * numWaves);
tangent.x -= Qi * wave.dir.x * wave.dir.y * WA * sin(rad);
tangent.z -= Qi * wave.dir.y * wave.dir.y * WA * sin(rad);
tangent.y += wave.dir.y * WA * cos(rad);
}
return normalize(tangent);
}
@fredgig
Copy link

fredgig commented Dec 2, 2020

This might be a shot in the dark, but would you happen to know how to calculate the height (Y) of the Gerstner wave at a given coordinate (X & Z)?

@claudijo
Copy link

This video explains how to get the height quite well https://youtu.be/kGEqaX4Y4bQ?si=3XuKA3FUnkIMw1hj&t=802

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment