【问题标题】:ThreeJS Stop RenderingThreeJS 停止渲染
【发布时间】:2014-07-09 08:21:05
【问题描述】:

我正在使用 ThreeJS 处理具有 OrbitControls 的基本 3d 场景。一切都很好,除了它会导致我的整个网站滞后,因为即使用户没有看它,它也会自行循环。我想要一个可以在满足某些条件时调用来启动和停止渲染的函数(在这种情况下,用户没有查看画布)。我有一个可以正常工作的启动功能,但停止功能似乎没有工作,因为我的网站在 ThreeJS 初始化后变得难以忍受。

我一直在寻找解决此问题的方法,并找到了几个“解决方案”,但无论出于何种原因,它们都不适用于我的应用程序。我的假设是这些解决方案来自旧版本的 ThreeJS。

这是我的 main.js 文件中的代码:

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;


}

在我的其他 javascript 文件中,我的 pageChange 函数(这是一个多页应用程序)内部有一个条件,如下所示:

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 在本地范围内的第二个 javascript 文件中较早地初始化。

任何帮助都将不胜感激,因为我不能让这个简单的 3D 场景在加载后滞后于我的整个应用程序。这不现实。

【问题讨论】:

  • 您的场景似乎是静态的。那是对的吗?如果是这样,您不需要每秒重新渲染 60 次。
  • 非常正确,除了控件之外,没有任何动画。出于某种原因,我认为为了让控件顺利运行,它需要以 60fps 的速度渲染。我会解决这个问题并会报告!
  • controls.addEventListener( 'change', render );
  • 极大地提高了性能。太感谢了!现在我只需要修改一些东西来隐藏画布或至少在不需要时禁用它的控件。有什么方法可以将您的回复转换为答案,以便我将其选为最佳答案?

标签: javascript three.js lag


【解决方案1】:

如果您的场景是静态的,则没有理由出现动画循环。您只需要在相机因鼠标或触摸事件而移动时重新渲染。

只需使用这种模式:

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

controls.addEventListener( 'change', render );

function render() {

    renderer.render( scene, camera );

}

three.js r.67

【讨论】:

  • 我这样做了,如果 event.target.id != "threeJS" 并且我的应用程序运行得更快、更高效,则返回 OrbitControls.js 文件。非常感谢您的帮助!
【解决方案2】:

我在我的场景中使用了轨迹球控件,因此无法使用上述解决方案(因为在鼠标事件完成触发后轨迹球控件会继续更新)。

为了解决这个问题,我使用了:

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

这会无限期地运行动画循环。要暂停动画,可以指定null 作为动画循环:

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

要恢复动画,只需再次传递动画循环:

renderer.setAnimationLoop(animate);     // resume the animation

【讨论】:

    【解决方案3】:

    完全停止渲染循环的另一种解决方案是降低每秒帧数,从而减少资源消耗。

    如果您需要对场景进行响应式更新而不一定是动画,但还需要在需要时恢复正常速度,则此方法特别有用。

    一个简单的 setTimout() 可以很好地实现这一点。

    var fps 10;
    
    function render() {
    
       //reduce framerate
       setTimeout(()=>{
    
            requestAnimationFrame(render);
    
            //must be called to enable rotating
            controls.update();
            renderer.render(scene, camera);
    
    
       }, 1000/fps)
    
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-24
      • 1970-01-01
      • 1970-01-01
      • 2013-07-06
      • 1970-01-01
      • 2019-11-07
      • 2021-06-22
      • 2016-12-26
      相关资源
      最近更新 更多