什么可以导致requestAnimationFrame在高效的webgl循环中删除帧?

Mic*_*ard 6 javascript google-chrome webgl requestanimationframe

我一直在编写一个javascript演示/测试来学习WebGL.我有一个相当有效的游戏循环结构(根据Chrome Dev Tools)只需1-2毫秒就可以运行.我正在使用requestAnimationFrame来安排循环的运行(因为这显然是执行60fps动画的"正确"方式).当我查看构造框架的时间轴时,实际的javascript代码是最小的,但框架的"空闲"部分可以将框架推到30 fps线以上.FPS计数器显示20-40fps,有很多滴(几乎像锯齿).

如果我的渲染循环已经是1-2毫秒,当它必须适合16毫秒运行60fps时,还有什么我可以解释的吗?

如果我将循环转换为setTimeout循环,它可以轻松容纳60fps.我甚至可以在Retina Resolution中渲染它而不会影响60fps.

例如

    // Timeout version
    function gameLoop()
{
setTimeout(gameLoop, 1000/60);
//Process movement, AI, game logic
 renderLoop();
}
function renderLoop()
{
//Drawing all of the 3d stuff
}
Run Code Online (Sandbox Code Playgroud)

VS

function gameLoop()
{
requestAnimationFrame(gameLoop);
//Process movement, AI, game logic
renderLoop()
}
Function renderLoop()
{
//draw objects
}
Run Code Online (Sandbox Code Playgroud)

我还在某个时候让gameLoop在setTimeout上"单独"运行,而renderLoop被requestAnimationFrame调用.因为它们都在同一个线程上,所以这看起来有点躲闪,因为它们可以踩到彼此的脚趾.

mok*_*oka 0

requestAnimationFrame不同浏览器的实现有所不同,并且由浏览器来维护其底层行为。

无法保证它会渲染 60fps,唯一保证您的函数将尽可能接近渲染时刻执行(就在交换缓冲区以将图像数据发送到屏幕之前)。

如果您使用 setTimeout,您可能会得到更频繁的函数调用,但这并不会给您带来必要的 60fps,因为屏幕可能仍以 30fps 或任何其他速度刷新。在这种情况下,您尝试渲染的频率太高 - 这会导致 GPU 和能源效率低下(尤其是在移动设备上)。

大多数人以单一频率(相同的功能)耦合更新和渲染逻辑。在任何情况下,您都需要使用增量时间修改器更新您的逻辑(速度等)。
这样,即使帧率为 30 fps,无论帧率如何,物体移动的速度都将相同。