I implemented "The Sum of Sines Approximation" in this article: https://developer.nvidia.com/gpugems/gpugems/part-i-natural-effects/chapter-1-effective-water-simulation-physical-models
My geometry is working fine, but the normals are somewhat wrong. They x- and z-values are flipped, and I wonder what i did wrong in the implementation.
The following equations are used:

The generation of the normals looks like this in the shader:
vec3 generateWaveSineSumNormal(sineParams _params[sineCount])
{
vec2 pos = vec2(aPos.x, aPos.z);
vec3 normal = vec3(0.0f, 1.0f, 0.0f);
for(int i=0; i<sineCount; i++)
{
sinParams curParams = _params[i];
normal.x += sineExponent * curParams.direction.x * curParams.frequency * curParams.amplitude *
pow((sin(dot(curParams.direction, pos) * curParams.frequency + curTime * curParams.speed)+1)/2, sineExponent-1)
* cos(dot(curParams.direction, pos) * curParams.frequency + curTime * curParams.speed);
normal.z += sineExponent * curParams.direction.y * curParams.frequency * curParams.amplitude *
pow((sin(dot(curParams.direction, pos) * curParams.frequency + curTime * curParams.speed)+1)/2, sineExponent-1)
* cos(dot(curParams.direction, pos) * curParams.frequency + curTime * curParams.speed);
}
return vec3(-normal.x, normal.y, -normal.z);
}
When the x- and z-values are flipped like this, the normals are fine. I'm just wondering what I did wrong implementing it, since I just can't find it.
Your normal.xz calculates the gradient of the heightmap correctly. The gradient points uphill, i.e. where the height values increase. The normal, when projected on the horizontal plane, would point backwards.
This can be derived mathematically through the use of cross-product of two tangents, which is what that article does in the "Normals and Tangents" section. In particular the relevant result is the formula for the normal in "Equation 6b", which includes the negative signs:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With