I've made a dudvMap to give my water a ripple effect, however it is giving it a repeated look and I can see the areas where two textures on the water meet

It's a little hard to see here, but if you look closely in the bottom center you can see the area where the four textures meet. How would I fix this? I thought about loading a single texture across the entire watertile, however then the ripple effect would be extremely stretched.

Here is my fragmentShader at the suggestion of @DMGregor

#version 400 core

in vec4 clipSpace;
in vec2 textureCoords;
in vec3 toCameraVector;

out vec4 out_Color;

uniform sampler2D reflection;
uniform sampler2D refraction;
uniform sampler2D dudvMap;
uniform float moveFactor;

const float strength = 0.1;

void main(void) {

    vec2 ndc = (clipSpace.xy/clipSpace.w)/2.0 + 0.5;
    vec2 refractCoords = vec2(ndc.x, ndc.y);
    vec2 reflectCoords = vec2(ndc.x, -ndc.y);

    vec2 distortion1 = (texture(dudvMap, vec2(textureCoords.x + moveFactor, textureCoords.y)).rg * 2.0 - 1.0) * strength;

    refractCoords += distortion1;
    refractCoords = clamp(refractCoords, 0.001, 0.999);

    reflectCoords += distortion1;
    reflectCoords.x = clamp(reflectCoords.x, 0.001, 0.999);
    reflectCoords.y = clamp(reflectCoords.y, -0.999, -0.001);

    vec4 reflectColour = texture(reflection, reflectCoords);
    vec4 refractColour = texture(refraction, refractCoords);

    vec3 viewVector = normalize(toCameraVector);
    float refractiveFactor = dot(viewVector, vec3(0.0, 1.0, 0.0));

    out_Color = mix(reflectColour, refractColour, refractiveFactor);


The way I load the image is pretty standard as well:

    waveFactor += WAVE_SPEED * DisplayManager.getFrameTimeSeconds();
    waveFactor %= 1;
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbos.getReflectionTexture());
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbos.getRefractionTexture());
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, dudvMap);
  • \$\begingroup\$ There are a lot of things that could cause this, including the texture map not being tileable, or adjacent tiles disagreeing about what lookup coordinates correspond to points along their shared edge. We'll need to see how you've set up your texture and the lookups into it to be able to diagnose the issue. \$\endgroup\$
    – DMGregory
    Jul 3, 2017 at 1:31
  • \$\begingroup\$ The fragment shader shows us only that you're using a variable called textureCoords — it does not show us how you've generated that value or how it varies over your tile. You also have not shown us your source texture so we can check that it tiles. \$\endgroup\$
    – DMGregory
    Jul 3, 2017 at 12:50

1 Answer 1


Check that your move factor no more than 1.0. This because when you are trying to add distortion moving to texture coords for dudv map and your value is more than 1.0. I know where your code comes from. I'm using C++ and can't use this dynamic type conversion from float to int. (waveFactor %=1)

Try to use this:

moveFactor += 0.01 * deltaTime;
moveFactor = moveFactor - int(moveFactor);

That works fine for me and this issue no longer occurs.


You must log in to answer this question.

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