ThreeJS Stop Rendering

ぐ巨炮叔叔 提交于 2020-12-29 04:38:04

问题


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.


回答1:


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




回答2:


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



回答3:


An alternative solution to completely stopping the render loop is to reduce the frames per second rate and thereby reducing resource consumption.

This approach is particularly useful if you need responsive update on your scene while not necessarily animating, but also need to snap back normal speeds when you need to.

a simple setTimout() achieves this nicely.

var fps 10;

function render() {

   //reduce framerate
   setTimeout(()=>{

        requestAnimationFrame(render);

        //must be called to enable rotating
        controls.update();
        renderer.render(scene, camera);


   }, 1000/fps)

};


来源:https://stackoverflow.com/questions/23770521/threejs-stop-rendering

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!