# Water wave simulation

I'm having a strange behavior simulating water waves. It works perfectly with directional waves, but point waves don't work like expected. If i do not normalize the directional vector(WoldPosition - waveCenter), it works like this: Which would be nice if i would want to display 10 point waves, but i just added one point wave(the center one). And if i do normalize the directional vector, it looks like this: Which is not even close of what a point wave should look like.

Do you have any idea of what could be the problem?

This is the formula used to calculate the heights of the waves:

amplitude * sin(dot(direction,vec2(x,z))*w + deltaTime*phase);


#version 330

layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 TexCoord;
layout (location = 2) in vec3 Normal;

uniform mat4 gWVP;
uniform mat4 gWorld;
uniform float gMatSpecularIntensity;
uniform float gSpecularPower;
uniform vec3 eyePoint;
uniform float deltaTime;

out vec2 TexCoord0;
out vec3 Normal0;
out vec3 WorldPos0;
out vec2 Specular0;
out vec4 wvp;
out float relativeFactor;

const float w = 1.2f;
const float amplitude = 0.1f;
const float phase = 2.2f;

vec3  wavePosition = vec3(20,0,20);

float CalculateHeight(float x, float z, vec2 direction)
{
return amplitude * sin(dot(direction,vec2(x,z))*w + deltaTime*phase);
}

vec3 CalculeNormal(float x, float z, vec2 direction)
{
float heightR = CalculateHeight(x-1,z,direction);
float heightL = CalculateHeight(x+1,z,direction);
float heightU = CalculateHeight(x,z+1,direction);
float heightD = CalculateHeight(x,z-1,direction);
return normalize(vec3((heightR - heightL),1, (heightU - heightD)));
}

void main()
{
wvp            = gWVP * vec4(Position, 1.0);
gl_Position    = wvp;
TexCoord0      = TexCoord;
WorldPos0      = (gWorld * vec4(Position, 1.0)).xyz;

vec2 direction = (wavePosition-WorldPos0).xz;

gl_Position.y  += CalculateHeight(WorldPos0.x,WorldPos0.z,direction);
Specular0      = vec2(gSpecularPower,gMatSpecularIntensity);
relativeFactor = dot(normalize(eyePoint - WorldPos0),vec3(0,1,0));

Normal0        = CalculeNormal(WorldPos0.x,WorldPos0.z,direction);
relativeFactor = clamp(relativeFactor, 0.0, 1.0);
}


Variables:

• direction: Vector which defines the direction of the wave. It is perpendicular to the wave front.
• x: Position x in world coordinates.
• z: Position z in world coordinates.
• amplitude: The amplitude of the wave
• phase: The phase of the wave
• deltaTime: The total time passed in ms.
• gWVP: Camera perspective matrix * Camera view matrix * Water transformation matrix (position matrix * rotation matrix(no rotation) * scale matrix)
• gWorld: Water transformation matrix (position matrix * rotation matrix(no rotation) * scale matrix)

The fragment shader and the other variables do not influence in the displayed wave, it just combine the reflextion + refraction image + apply the fresnel efect.

• Can you define your variables here? Is direction the vector you described as (WoldPosition - waveCenter)? What are x, z, and w? – DMGregory Dec 16 '16 at 22:09
• Yes of course, ill paste the shaders and define them. Let me a minute. – Haruko Dec 17 '16 at 8:42
• This is just a guess, but try moving normalization to the fragment shader. Normalizing before the fragment interpolation causes problems in some situations. – msell Dec 17 '16 at 9:07
• @msell I have to normalize the direction (the wave direction vector) in the vertex shader, because this vector is used to calculate the y component of the vertices. Then because the vertices positions must be solved in the vertex shader, i can not move it to the fragment shader. But i'll keep it in mind for future implementations. – Haruko Dec 17 '16 at 9:33
• Where did you get that formula from? It isn't what I'd expect for a non-directional/point wave. (For one thing, why does your non-directional wave formula include a direction?!) – user253751 Dec 19 '16 at 3:59

• ... + deltaTime * phase: Should that be a multiplication, not an addition? I've never added phase to anything, always multiplied.