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);
Vertex shader:
#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.
For more info about the wave function: http://http.developer.nvidia.com/GPUGems/gpugems_ch01.html
direction
the vector you described as(WoldPosition - waveCenter)
? What arex
,z
, andw
? \$\endgroup\$