Search code examples
javascriptthree.jsvertex-shader

Keep movement of vertexShader despite of its mesh rotation


I'm simply moving the vertices of my cube following the y axis.

It works fine but when I start rotating my cube, the movements stays at the global y axis. Does anyone know how to prevent this behavior? Meaning having the rotation and the movement of my vertices separated?

https://codepen.io/michaelgrc/pen/JjrMVPm?editors=0010

void main()
{
    vec4 modelPosition = modelMatrix * vec4(position, 1.0);

    float deplacement = sin(uTime) * 2.;
    modelPosition.y += deplacement;

    vec4 viewPosition = viewMatrix * modelPosition;
    vec4 projectedPosition = projectionMatrix * viewPosition;

    gl_Position = projectedPosition;
}

Solution

  • Matrix operations are not Commutative. What you actually do is translate the model after applying the modelMatrix:

    v' = translate * modelMatrix * v;
    

    However you have to apply the tranaltion first:

    v' = modelMatrix * translate * v;
    

    e.g.:

    void main()
    {
        mat4 translate = mat4(1.0);
        translate[3].y = sin(uTime) * 2.0;
        vec4 modelPosition = modelMatrix * translate * vec4(position, 1.0);
    
        gl_Position = projectionMatrix * viewMatrix * modelPosition;
    }
    

    Note, the same can be achieved with a Group. The rotation has to be applied to the Group and the translation to the Mesh in the Group.

    group = new THREE.Group();
    group.add(mesh);
    
    mesh.position.y = offset;
    group.rotation.x = angle_x;
    group.rotation.y = angle_y;