Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThreeJS Stop Rendering

I am working with ThreeJS on a basic 3d scene that has OrbitControls. Everything works great, except it causes my entire site to lag, as it is looping itself even when the user is not looking at it. I want a function that I can call to start and stop the rendering when certain conditions are met (in this case, the user isn't viewing the canvas). I have a start function that works just fine, but the stop function does not seem to be working, as my site goes unbearably slow after ThreeJS has initialized.

I have looked and looked for a solution to this problem, and have found a couple 'solutions', but for whatever reason they do not work with my application. My assumption is that these solutions are from old versions of ThreeJS.

Here is my code in my main.js file:

var scene, 
    camera, 
    controls,
    render,
    requestId = undefined;


function init() {
    scene = new THREE.Scene();
    var threeJSCanvas = document.getElementById("threeJS");
    camera = new THREE.PerspectiveCamera( 75, threeJSCanvas.width / threeJSCanvas.height, 0.1, 1000 );

    controls = new THREE.OrbitControls( camera );

    // Controls and Camera settings

    // Create Geometry.

}

function render() {
    requestId =  requestAnimationFrame(render);
    renderer.render(scene, camera);

}

function start() {
    render();
}

function stop() {
   window.cancelAnimationFrame(requestId);
   requestId = undefined;


}

In my other javascript file, there is a conditional inside of my pageChange function (this is a multipage app), that looks like the following:

if (page == 5) { // The page with the canvas on it
    if (!locationsRendered) {
    init();
    locationsRendered = true;
}
} else { // If the page is not the page with the canvas on it
    if (locationsRendered) {
        stop();
    }
}

locationsRendered is initialized earlier in this second javascript file in the local scope.

Any help would be much appreciated, as I can not let this simple 3D scene lag my entire app after it has been loaded. It's just not realistic.

like image 347
Bjornir Avatar asked May 20 '14 21:05

Bjornir


2 Answers

If your scene is static, there is no reason for an animation loop. You only need to re-render when the camera moves due to a mouse or touch event.

Just use this pattern:

controls = new THREE.OrbitControls( camera, renderer.domElement );

controls.addEventListener( 'change', render );

function render() {

    renderer.render( scene, camera );

}

three.js r.67

like image 62
WestLangley Avatar answered Nov 06 '22 01:11

WestLangley


I was using trackball controls in my scene and therefore couldn't use the solution above (as the trackball controls continue updating after mouse events finish triggering).

To solve this problem, I used:

function animate() {
  renderer.render(scene, camera);
  controls.update();
}
renderer.setAnimationLoop(animate);

That runs the animation loop indefinitely. To pause the animation, one can then specify null as the animation loop:

renderer.setAnimationLoop(null);        // pause the animation

And to resume the animation, just pass the animation loop again:

renderer.setAnimationLoop(animate);     // resume the animation
like image 1
duhaime Avatar answered Nov 06 '22 00:11

duhaime