4
\$\begingroup\$

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: enter image description here

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:

enter image description here

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

\$\endgroup\$
  • \$\begingroup\$ Can you define your variables here? Is direction the vector you described as (WoldPosition - waveCenter)? What are x, z, and w? \$\endgroup\$ – DMGregory Dec 16 '16 at 22:09
  • \$\begingroup\$ Yes of course, ill paste the shaders and define them. Let me a minute. \$\endgroup\$ – Haruko Dec 17 '16 at 8:42
  • \$\begingroup\$ This is just a guess, but try moving normalization to the fragment shader. Normalizing before the fragment interpolation causes problems in some situations. \$\endgroup\$ – msell Dec 17 '16 at 9:07
  • \$\begingroup\$ @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. \$\endgroup\$ – Haruko Dec 17 '16 at 9:33
  • \$\begingroup\$ 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?!) \$\endgroup\$ – immibis Dec 19 '16 at 3:59
-1
\$\begingroup\$

This is a little over my head, but it looks super interesting. Will you bear with my while I throw out some dumb ideas?

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

  • How are multiple waves combined? Apparently, something in the wave summing function compensates for a problem in the wave amplitude function.

  • One thing that helps me with math-in-code debugging, is to graph out the terms of the equation, over the interesting part of their input domain. You might be able to see the problem right away, and narrow down the cause to a part of one of the wave-related functions.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.