36

我在想,对于一些我做的项目,60fps 并不是完全需要的。我想我可以拥有更多以 30fps 运行的对象和事物,如果我能让它以该帧速率平稳运行的话。我想如果我在 three.js 中编辑 requestAnimationFrame 垫片,我可以将它限制为 30。但我想知道是否有更好的方法来使用所提供的three.js 本身。此外,这会给我带来我所想的那种性能提升吗?我能以 30 fps 渲染两倍于 60 fps 的对象吗?我知道以 30 和 60 运行的东西之间的区别,但我能否让它以平稳的恒定 30fps 运行?

我通常使用 WebGLRenderer,如果需要,我会回退到 Canvas,除非项目专门针对它,通常是 webgl 着色器项目。

4

5 回答 5

81

像这样的东西怎么样:

function animate() {

    setTimeout( function() {

        requestAnimationFrame( animate );

    }, 1000 / 30 );

    renderer.render();

}
于 2012-07-02T14:15:17.650 回答
14

这种方法也可以工作,使用 THREE.Clock 来测量增量。

let clock = new THREE.Clock();
let delta = 0;
// 30 fps
let interval = 1 / 30;

function update() {
  requestAnimationFrame(update);
  delta += clock.getDelta();

   if (delta  > interval) {
       // The draw or time dependent code are here
       render();

       delta = delta % interval;
   }
}
于 2018-08-21T06:42:43.267 回答
6

CPU 和 GPU 需要做的工作量取决于工作负载,它们设置了平滑帧速率的上限。

  • GPU 主要以线性方式工作,并且总是可以将相同数量的多边形推送到屏幕上。

  • 但是,如果您将对象数量增加了一倍,CPU 必须更加努力地为所有对象设置动画(矩阵变换等)。这取决于您的世界模型和其他工作 Javascript 会提供多少额外开销。此外,可见物体的数量等条件也很重要。

对于所有多边形始终在屏幕上的简单模型,它应该几乎遵循“一半帧速率,双倍对象”的规则。对于类似 3D 射击游戏的场景,这绝对不是这种情况。

于 2012-07-02T08:52:40.410 回答
5

我遇到了这篇文章,它提供了两种解决自定义帧速率问题的方法。

http://codetheory.in/controlling-the-frame-rate-with-requestanimationframe/

我认为这种方式更健壮,因为即使在不能以 60 fps 始终如一地渲染画布的计算机上,它也将具有稳定的动画速度。下面是一个例子

var now,delta,then = Date.now();
var interval = 1000/30;

function animate() {
    requestAnimationFrame (animate);
    now = Date.now();
    delta = now - then;
    //update time dependent animations here at 30 fps
    if (delta > interval) {
        sphereMesh.quaternion.multiplyQuaternions(autoRotationQuaternion, sphereMesh.quaternion);
        then = now - (delta % interval);
    }
    render();
}
于 2017-12-11T21:06:09.047 回答
3

与不限制 fps 相比,接受的答案有问题,并且在慢速计算机上最多放弃 -10fps,例如不限制 36pfs,接受的解决方案为 26fps(对于 60fps,1000/60 setTimeout)。

相反,您可以这样做:

var dt=1000/60;
var timeTarget=0;
function render(){
  if(Date.now()>=timeTarget){

    gameLogic();
    renderer.render();

    timeTarget+=dt;
    if(Date.now()>=timeTarget){
      timeTarget=Date.now();
    }
  }
  requestAnimationFrame(render);
}

如果它已经落后,这种方式不会等待。

于 2019-08-25T02:55:50.593 回答