So I wrote this GLSL fragment shader for shadertoy:
const float INTENSITY = 0.5;
const float SPEED = 0.5;
const float SIZE = 0.2;
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
vec4 color = texture(iChannel0, uv);
vec2 ghostOffset = vec2(cos(uv.y * SPEED * sin(iTime)), sin(uv.x * SPEED));
color += INTENSITY * texture(iChannel0, uv + ghostOffset * SIZE);
fragColor = color;
}
https://www.shadertoy.com/view/dsjXD3
However, the resulting image seems to wrap over at the side. I know why this happens (UV is getting above {1., 1.}
or below {0., 0.}
), but I don't know how to fix it. Do you have any suggestions?
Thanks
Tuxifan
the problem comes from the fact that when
uv.y == 0
,cos(uv.y * SPEED * sin(iTime)) == cos(0) == 1
. So at the bottom of the image there is a constant offset which is equal toSIZE
. To fix that you could just use a sin instead of the cos but then there would be no horizontal distortion at the bottom. You can also defineghostOffset
as follows:With this, the distortion at the borders will always be parallel to them. It works because
x * (1 - x) == 0
ifx == 0
orx == 1
which is the case at the borders of the image. Note that you can put whatever you want inside the sin functions (you can even replace them by another function), the distortion at the borders of the image will always be parallel to the borders. I hope this helps. If it doesn't, tell me why.