Issue with shader size

Hi,
I’ve followed a few tutorials and successfully set a scene in ThreeJS that emulates sort of wavy movement on mouseover.

As I am not really experience with ThreeJS I encountered an issue that I can’t seem to solve.
After some research I realised my shader is not set properly, and it results in an stretched image that doesn’t cover the whole width of the container – resulting in this ugly pixel expand on the edges.

I realised that my camera and scene is built correctly, but something’s not right with the shader.

Essentially, what I need is for this image to cover the whole width of the window, without wrapping the edges.

Can someone help me spotting where the problem is?


const vertex = `precision mediump float;
uniform float u_time;
varying vec3 texcoords;
uniform float u_amplitude;
uniform float u_freq;
uniform vec2 u_mouse;

void main() {
  vec2 st = position.xy / 30.;
  vec2 mc = u_mouse - 0.4;

  vec2 point = vec2(0.5);

  float l = length(vec2(st.x - mc.x, st.y + mc.y));
  float angle = (u_time*0.5 + l*30.) * u_freq;

  float oscillation =  sin(angle) * u_amplitude;

  gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xy, oscillation, 1.0);
  texcoords =  vec3(position.xy, oscillation);
}
`;

const fragment =  `precision mediump float;
uniform vec2 u_res;
uniform sampler2D u_texture;
varying vec3 texcoords;
uniform float u_amplitude;

void main() {
  vec2 a = texcoords.xy / 30. + 0.5;
  gl_FragColor = mix(texture2D(u_texture, a), vec4(vec3(0.0),1.),-texcoords.z/u_amplitude/8.);
}
`;

Thanks a lot in advance.

The problem is that your uv coordinates go outside [0,1] interval, basically outside the texture and you get whatever texture wrap mode gives you, in your case clamp to edge pixels.

I wouldn’t use vertex shader to make waves as barycentric interpolation doesn’t really help you to carry them to fragment shader.

Wavy distortion can be done in one line of code in fragment shader, like so:

uv.x = 0.5 * (1.0 + amp * sin(freq * vuv.y + time)) + (1.0 - amp) * (uv.x - 0.5);

instead of sampling your texture horizontally from [0,1] you sample symmetrically around the center 0.5, and then shift that 0.5 center point depending on the vertical uv component and, in this case, time. In your case it’s going to be something depending on the mouse position.