Image / Video Distortion Effect


I’ve been coding for a few years but I’m very new to Three JS and wanted to see if someone could point me in the right direction. I want to create a distortion effect on an image or video element with possibly a displacement map, however, I want to stretch or distort some of the pixels technically off of the HTML element (Imagine an image that doesn’t take up the full size of the canvas) but onto the empty canvas. My goal would be to eventually animate this effect but for now, I’m just trying to get the initial setup.


In this case, you should start with EffectComposer since you basically want to implement some sort of post-processing. There are a lot of different three.js examples about post-processing and even more interesting code on sites like shadertoy. Shadertoy code can of course be used three.js applications however it require some migration effort (in order to provide the same uniforms, textures etc.).

1 Like

Thanks Mugen87, so I looked into Three.js and shaders and learned some of the basics. Now I’m trying to use a video in my fragment shader but it’s not working. I also have a vertex shader that’s distorting a plane buffer geometry. I’m not sure if I’m loading the video properly or what I’m doing incorrectly. If I comment out my shader code related to the video, I don’t get any errors.

/* Part of error */
THREE.WebGLProgram: shader error: 0 35715 false gl.getProgramInfoLog invalid shaders THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 0:111: ‘void’ : syntax error
1: precision highp float;
2: precision highp int;
4: #define SHADER_NAME ShaderMaterial
5: #define GAMMA_FACTOR 2…

/* Sample JS Code */

var video = document.querySelector(‘video’);;
var texture = new THREE.VideoTexture(video);
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;

var customUniforms = {
video: {
type: “t”,
value: texture

/* fragment shader */

varying vec2 vUv;
uniform sampler2D video;

void main() {
vec3 color = texture2D(video, vUv);
gl_FragColor = vec4( color, 1.0 );

I was able to solve the issue. For anyone else this might help:

vec4 color = texture2D(video, vUv);
gl_FragColor = vec4(color);