我一直在编写一个javascript演示/测试来学习WebGL。我有一个相当有效的游戏循环结构(根据Chrome Dev Tools)只需1-2毫秒就可以运行。我正在使用requestAnimationFrame来安排循环的运行(因为这显然是执行60fps动画的“正确”方式)。当我查看构造框架的时间轴时,实际的javascript代码是最小的,但框架的“空闲”部分可以将框架推到30 fps线以上。 FPS计数器显示20-40fps,有很多滴(几乎像锯齿)。
如果我的渲染循环已经是1-2毫秒,当它必须适合16毫秒才能运行60fps时,还有什么我可以解释的吗?
如果我将循环转换为setTimeout循环,它可以轻松容纳60fps。我甚至可以在Retina Resolution中渲染它而不会影响60fps。
e.g。
// Timeout version
function gameLoop()
{
setTimeout(gameLoop, 1000/60);
//Process movement, AI, game logic
renderLoop();
}
function renderLoop()
{
//Drawing all of the 3d stuff
}
v.s。
function gameLoop()
{
requestAnimationFrame(gameLoop);
//Process movement, AI, game logic
renderLoop()
}
Function renderLoop()
{
//draw objects
}
我还在某个时候让gameLoop在一个setTimeout上“单独”运行,而renderLoop被requestAnimationFrame调用。因为他们都在同一个线程上,所以这看起来有点躲闪,因为他们可以踩到彼此的脚趾。
答案 0 :(得分:-1)
requestAnimationFrame
实现在不同的浏览器中有所不同,并且由浏览器来维护它的基本行为。
不能保证它会渲染60fps,唯一可以保证你的函数尽可能接近渲染时(就在交换缓冲区以将图像数据发送到屏幕之前)。
如果你使用setTimeout,你可能会得到更频繁的函数调用,但这不会给你60fps,因为屏幕可能仍然以30fps或其他任何方式刷新。在这种情况下,你试图经常渲染 - 这就是gpu和能源效率低下(特别是在移动设备上)。
大多数人将他们的更新和渲染逻辑以单一频率(相同的功能)结合在一起。在任何情况下,您都需要使用delta-time修改器更新逻辑(速度等) 即使使用30fps,移动速度也会相同,无论fps如何。