Advertisement Jump to content
Sign in to follow this  

How to implement wave equation?

This topic is 924 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm using OpenGL, GLFW and GLEW to create a simulation of water waves for a school project.

When I use the old vertex shader without the function, the grid renders as expected, but with the new shader it shows a blank grey background.
I created a grid in the xz-plane and created a shader to manipulate the grid based on an equation I found from some resources I found online are at the end:
Here are the relevant snippets of code:

Rendering code

        // Set frame time
        GLfloat currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;

        // Check and call events


        // Clear the colorbuffer
        glClearColor(0.2f, 0.2f, 0.2f, 1.0f);

        // Draw objects

        //Set Uniforms
        GLint locTime = glGetUniformLocation(shader.Program, "time");
        if (locTime != -1)
            glUniform1f(locTime, (float)glfwGetTime());

        GLint locWLength = glGetUniformLocation(shader.Program, "wavelength");
        if (locWLength != -1)
            glUniform1f(locWLength, 1.0f);

        GLint locPeak = glGetUniformLocation(shader.Program, "peak");
        if (locPeak != -1)
            glUniform1f(locPeak, 3.0f);

        glm::mat4 model;
        glm::mat4 view = camera.GetViewMatrix();
        glm::mat4 projection = glm::perspective(camera.Zoom, (float)screenWidth/(float)screenHeight, 0.1f, 100.0f);
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));

        // Grid
        glBindTexture(GL_TEXTURE_2D, floorTexture);
        model = glm::mat4();
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
        //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        glDrawElements(GL_LINES, 3*grid.Indices.size(), GL_UNSIGNED_INT, 0);

        // Swap the buffers


Vertex Shader

#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoords;

out vec2 TexCoords;

const float pi = 3.14159265;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

uniform float wavelength;
uniform float peak;
uniform float time;

void main()
    float a = position.x;
    float b = peak - 1.0f;
    float k = (2.0f * pi) / wavelength;
    float c = sqrt(9.81f/k);

    float wave_dx = (exp(k * b)/ k) * sin(k * (a + c * time));
    float wave_dy = (-exp(k * b)/ k) * cos(k * (a + c * time));    

    gl_Position = projection * view * model * vec4( (position.x + wave_dx), (position.y + wave_dy), position.z, 1.0f);
    TexCoords = texCoords;


oldVertex Shader

#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoords;

out vec2 TexCoords;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
    gl_Position = projection * view * model * vec4(position, 1.0f);
    TexCoords = texCoords;

Here is the correct static output:





This is where I got my equation/ implementation.

" title="External link">


Thanks in advance!


Share this post

Link to post
Share on other sites

A lot of things could be wrong here - including compile/link errors with the shaders - if not then likely your equations are producing huge delta values.


I would start with a simple traveling wave in a single direction - assuming your water is in x y plane then just vary z according to time and either x/y - expand from there.


new_z = position.z * A * sin( 2 * pi * f * time - beta * position.x) // varying according to x


where A is the amplitude, f is the frequency in hertz, and beta is 2 * pi * f / phase_velocity. Most emag wave equations would assume a phase velocity of the speed of light, but I would chose a more sane and visible phase velocity.


If you want the wave to travel across your water in the x direction at 1 unit per second for example and you want the wave to complete an up/down cycle once per second: f = 1, beta = 2 * pi * f / phase_velocity = 2 * pi 


which lands you at


new_z = position.z * A * sin(2 * pi * (time - position.x) )


You could adjust A, starting very small, until you see noticeable waves going in the x direction across the water. Start adding to get to the other wave equations from there.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!