javascriptthree.jsrt

Three.js - issue with rendering - animation is shaking


I get a strange problem with the rendering of a sphere in rotation : the animation seems to shake and I don't know where this issue comes from.

Here's the example on this link

and the render function :

 function render() {

  controls.update();
  requestAnimationFrame(render);

  // For camera rotation : parametric parameter 
  timer = Date.now()*0.0001;

  // Coordinates of camera
  coordCamera.set(radiusCamera*Math.cos(timer), radiusCamera*Math.sin(timer), 0);

  // Rotate camera function
  rotateCamera();

  // Rendering
  renderer.render(scene, camera);

  }

with rotateCamera and computeRotation functions :

function computeRotation (objectRotation, coordObject) {

  // Apply rotation matrix 
  var rotationAll = new THREE.Matrix4();
  var rotationX = new THREE.Matrix4().makeRotationX(objectRotation.rotation.x);
  var rotationY = new THREE.Matrix4().makeRotationY(objectRotation.rotation.y);
  var rotationZ = new THREE.Matrix4().makeRotationZ(objectRotation.rotation.z);
  rotationAll.multiplyMatrices(rotationX, rotationY);
  rotationAll.multiply(rotationZ);

  // Compute world coordinates 
  coordObject.applyMatrix4(rotationAll);

  }

  function rotateCamera() {

  // Compute coordinates of camera
  computeRotation(torus, coordCamera);

  // Set camera position for motion
  camera.position.set(coordCamera.x, coordCamera.y, coordCamera.z)

  }

If someone could see what's wrong, this would be nice,

Thanks for your help

UPDATE :

I tried to insert the solution below of ; I didn't get to make work the animation, nothing is displayed : here my attempt on jsfiddle :

https://jsfiddle.net/ysis81/uau3nw2q/5/

I tried also with performance.now() but animation is still shaking; you can check this on https://jsfiddle.net/ysis81/2Lok5agy/3/

I have started a bounty to resolve maybe this issue.


Solution

  • requestAnimationFrame will execute your callback render function with a timestamp parameter. Use that parameter to calculate how many milliseconds have passed since the last frame. Then use that diff as some percentage of rotation.

    var mySpecificLogic = function (millesecondsSinceLastFrame) {
      // rotate your camera here
      // if you want it to rotate 20 degrees every second
      var rotPerSecond = 20;
      var rotationPerMS = rotPerSecond / 1000;
      var rotationInDegrees = millesecondsSinceLastFrame * rotationPerMS;
      // call your rotation function
      // note: if you are also trying to move the ball with the mouse
      //    you'll want a hook to disable this basic rotation
    
      // set the camera to whatever rotation you want
    
      renderer.render(scene, camera);
    };
    
    
    var startTheWholeThing = function() {
        var lastFrameTime;
        var deltaT;
    
        function recurse( thisFrameTime ) {
            window.requestAnimationFrame(recurse);
            lastFrameTime = lastFrameTime || thisFrameTime;
            deltaT = thisFrameTime - lastFrameTime;
    
            mySpecificLogic(deltaT);
    
            lastFrameTime = thisFrameTime;
        }
      recurse();
    };
    
    startTheWholeThing();