I'm attempting to add reflective water to my procedural terrain. I've got it to a point which seems like it's reflecting however when I move the camera left/right/up/down the reflections move with it.

I believe the problem has something to do with the way I convert from world space to clip space for the projective texture mapping.

Here is a gif of what is happening. http://i.imgur.com/PDta5Qu.gifv

Vertex Shader

#version 400
in vec4 vPosition;
out vec4 clipSpace;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main ()
  clipSpace = projection * view * model * vec4(vPosition.x, 0.0, vPosition.z, 1.0);
  gl_Position = clipSpace;

Fragment Shader

#version 400
in vec4 clipSpace;
out vec4 frag_colour;
uniform sampler2D reflectionTexture;

void main ()
    vec2 ndc = (clipSpace.xy / clipSpace.z) / 2.0 + 0.5;
    vec2 reflectTexCoords = vec2(ndc.x, -ndc.y);
    vec4 reflectColour = texture(reflectionTexture, reflectTexCoords);

    frag_colour = reflectColour;

I'm using this code to move the camera under the water's surface to get the reflection

float distance = 2 * (m_camera->GetPosition().y - m_water->GetHeight());
m_camera->m_cameraPosition.y -= distance;
m_camera->m_cameraPitch = -m_camera->m_cameraPitch;

If this is insufficient code to diagnose the problem, I'll post more. I tried to keep it to what I thought could be the problem.

  • \$\begingroup\$ Hey as a small note, using a link to an actual gif, or uploading it to stack's imgur account (using the edit tool bar icon), you could integrate the image to the post, which could improve readers experience :) \$\endgroup\$
    – Vaillancourt
    Mar 7, 2017 at 12:58
  • \$\begingroup\$ Do you render the scene from a camera below the surface or do you simply use the main camera's images as a reflection texture? \$\endgroup\$
    – Bálint
    Mar 7, 2017 at 20:28
  • \$\begingroup\$ I move the main camera down below the surface, push the scene to a FBO and then move my main camera back up to its original location to use in the main render. \$\endgroup\$
    – tuckismad
    Mar 8, 2017 at 6:53

1 Answer 1


The code corresponds to the very good Water Tutorials from ThinMatrix. I also had the same problem with the camera today. I forgot that changing the Pitch requires an update of the camera vectors - especially the Front-Vector. In the InvertPitch() function, the Update function of the camera class must be called:

void sg::ogl::camera::LookAtCamera::InvertPitch()
    m_pitch = -m_pitch;

    // Update Front, Right and Up Vectors using the updated Euler angles.

void sg::ogl::camera::LookAtCamera::Update()
    // Calculate the new Front vector.
    glm::vec3 front;
    front.x = cos(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
    front.y = sin(glm::radians(m_pitch));
    front.z = sin(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
    m_front = normalize(front);

    // Calculate the new Right and Up vector.
    m_right = normalize(cross(m_front, m_worldUp));
    m_up = normalize(cross(m_right, m_front));

Now the right ViewMatrix can be created:

glm::mat4 sg::ogl::camera::LookAtCamera::GetViewMatrix() const
    return lookAt(m_position, m_position + m_front, m_up);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .