Warping effect on a plane

Hello Everyone

I recently try to implement a carrousel with a warping effect based on this codrops article.
I refactored the project by migrating it on Vue and using an OrthographicCamera.

My goal
Getting the same warping effect on drag

My problem
As you can see on my codesandbox I think i’m not far of the truth.

I’ve got the main points of the code but the only thing I don’t understand is the GLSL part :exploding_head:

uniform vec2 uOffset;
varying vec2 vUv;
vec3 deformationCurve(vec3 position, vec2 uv, vec2 offset) {
  float M_PI = 3.1415926535897932384626433832795;
  position.x = position.x + (sin(uv.y * M_PI) * offset.x);
  position.y = position.y + (sin(uv.x * M_PI) * offset.y);
  return position;
void main() {
  vUv =  uv + (uOffset * 2.);
  vec3 newPosition = position;
  newPosition = deformationCurve(position, uv, uOffset);
  gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );

I know that all the logic of the deformation is in it but can someone could explain how this shader works and what’s wrong in my code ?

I’ve understood some basics of this part but getting lost on the declaration of uv and vUv.

I’ve looked the openGL doc but don’t find the answers to my questions

Thank you in advance for your responses :+1:

There’s some weird ancient magic happening in the code - the strength is a bit too small to see any effect - but your main issue seems to be the calculation of strength vector.

You pass Three.Vector3 as vec2 vOffset. The y value of the strength vector you pass is always 0, that’s why you can’t see any effect in the shader. It should be enough to pass:

this.uniforms.uOffset.value = new THREE.Vector2(offset.x, offset.z);

And adjust the scale of the strength displacement (I kept the original value of strength at 0.00075):

position.x = position.x + (sin(uv.y * M_PI)) * offset.x * 1000.;
position.y = position.y + (sin(uv.x * M_PI)) * offset.y * 1000.;

Hi @mjurczyk

Thank you for your fast answer
I’ve tried your solution but didn’t get the effect :confused:
I think that’s my problem is rather on the value of uv.y.

I don’t get very well the functionnaluty of it but it seems to control the derformation on x axis.

On the absolute I just realized that I don’t need the position.y because I only want a deformation on x axis.

I’m going to continu to work on this, if you have any other idea, don’t hesitate to share it or directly edit my sandbox (I have a local copy of it) ^^

Anyway thank you for your reactivity, realy appreciate it !

Sorry for my occasional bad english, I’m French and try to do my best haha

I copied the code directly from a working codesandbox, if you paste it there it should work :thinking: (I’m not sure if you modified something else in your local code, or maybe I forgot smthn.)


Hum It was surely me who made a mistake, I update the sandbox with your code so you can see if i missed something :wink:

I think it would be easier if you’d revert the code to the initial state. Right now, indeed, it does not work.

Okay !
The sandbox is currently as at the start.
I will continue my research, I know there really isn’t much missing for this to works ^^

Ah, yes, I did forget. Subdivide the plane more in the constructor - you don’t see difference because there’s simply not enough vertical vertices to move around (+ the code I shared above):

const geometry = new THREE.PlaneBufferGeometry(
1 Like

It works !
Thanks a lot for all your answers.
I will continue to work on this to better understand the GLSL part ! :+1: