【问题标题】:Limiting framerate in Three.js to increase performance, requestAnimationFrame?在 Three.js 中限制帧速率以提高性能,requestAnimationFrame?
【发布时间】:2012-07-02 08:37:19
【问题描述】:

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

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

【问题讨论】:

    标签: javascript html canvas three.js requestanimationframe


    【解决方案1】:

    接受的答案有问题,与不限制 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);
    }
    

    如果它已经落后了,那就不用等待了。

    【讨论】:

      【解决方案2】:

      这种方法也可以使用,使用 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;
         }
      }
      

      【讨论】:

      • 这比公认的答案更好,至少对我来说。使用 setTimeout 方法时,我的精灵动画会在每次循环后暂停几毫秒。此建议没有这样的负面影响,同时仍能同样有效地降低 CPU 负载。
      • 我认为你应该这样做,聪明又干净。在一秒钟内多次调用 setTimeout 时,我在记忆方面也不太舒服。它可能完全没问题,但仍然。
      【解决方案3】:

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

      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();
      }
      

      【讨论】:

        【解决方案4】:

        这样的事情怎么样:

        function animate() {
        
            setTimeout( function() {
        
                requestAnimationFrame( animate );
        
            }, 1000 / 30 );
        
            renderer.render();
        
        }
        

        【讨论】:

          【解决方案5】:

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

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-04-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-02-23
            • 1970-01-01
            相关资源
            最近更新 更多