我使用了Paul Irish的剧本 https://gist.github.com/paulirish/1579671 在html网站内创建动画循环。
虽然它在全屏模式下比在浏览器窗口中更快但它仍然有效。 此外,我根据画布大小和我使用的浏览器观察到不同的速度。
问题:如何使用脚本确保稳定的帧速率?
此处提供代码(由Web Danchilla开始WebGL,第1章): https://github.com/bdanchilla/beginningwebgl/blob/master/01/2D_movement.html
答案 0 :(得分:2)
修饰@emackey所说的,
简短的回答是你不能。您可以要求计算机每帧执行无限量的工作。我不能保证在有限的时间内完成这项工作。
最重要的是,每台计算机都有不同的功率。廉价的集成GPU比高端显卡的功耗要低得多。 intel i3比i7慢得多。
您还提到了更改画布大小。绘制300x150画布的工作量仅为45000像素。绘制1920x1080画布将是2,073,600像素的工作或46倍的工作
您可以做的最好的事情是尽可能少地完成工作,或者自动或通过用户选择删除慢速硬件上的功能。大多数游戏都这样做。它们是图形设置选项,用户可以选择分辨率,纹理分辨率,反对等级和各种其他东西。
也就是说,您可以尝试进行计算,以便应用程序中的内容相对于时间以一致的速度移动。慢速机器或较大的画布上的帧速率可能较慢,但每秒移动的距离将保持不变。
您可以使用传递到requestAnimationFrame
function render(time) {
// time is time in milliseconds since the page was loaded
...do work...
requestAnimationFrame(render);
}
requestAnimationFrame(render);
例如,这里是 NON 帧速率独立动画
function render(time) {
xPosition = xPosition + velocity;
...
requestAnimationFrame(render);
}
requestAnimationFrame(render);
这里是帧率独立动画
var then = 0;
function render(time) {
var timeInSeconds = time * 0.001;
var deltaTimeInSeconds = timeInSeconds - then;
then = timeInSeconds;
xPosition = xPosition + velocityInUnitsPerSecond * deltaTimeInSeconds;
...
requestAnimationFrame(render);
}
requestAnimationFrame(render);
注意:传递到requestAnimationFrame的时间比Date.now()
答案 1 :(得分:1)
这样的事情应该有效。如果两帧之间的时间差小于FPS限制,则更新函数将返回并等待下一帧。但这只会限制更新发生得太快;就像emackey说的那样,更新循环总是有可能运行得更慢。
var updateId,
previousDelta = 0,
fpsLimit = 30;
function update(currentDelta) {
updateId = requestAnimationFrame(update);
var delta = currentDelta - previousDelta;
if (fpsLimit && delta < 1000 / fpsLimit) {
return;
}
/* your code here */
previousDelta = currentDelta;
}
答案 2 :(得分:0)
您无法直接强制执行稳定的帧速率。您的页面不是用户平台上运行的唯一应用程序,平台功能差异很大。 requestAnimationFrame
尽可能快地运行,不超过目标设备上的显示更新间隔,但可能会慢得多,具体取决于可用的CPU,GPU,内存和其他限制。
此处的标准做法是测量自上一个动画帧以来经过的时间量,通常使用Date.now(),并且每个帧将动画推进该时间量。对于人眼来说,这使得生成的动画以一致的速度运行,即使帧速率变化很大。
例如,Shadertoy和GLSL Sandbox这样的网站会运行全屏GLSL着色器,并传入一个名为time
(或iGlobalTime
)的统一,这是一个{ {1}}表示自着色器启动以来经过的秒数。此时间值以不规则的间隔增加,具体取决于每个动画帧渲染的时间长度,但结果是浮动似乎以每秒1.0的稳定速度向上计数。通过这种方式,基于此时间值的着色器播放可以显示一致。