Html帆布1600x1200屏幕撕裂

时间:2013-11-20 00:03:39

标签: javascript html canvas windows-8

我已经看过几个问题,但是他们已经三年多了,并且通常最后说的还没有解决它,所以我想知道是否有任何改变。

我正在开发一款使用每秒发生60次的间隔绘制到画布上的游戏。它在我的iphone和PC上工作得很好,它有一个不错的显卡,但我现在正在尝试使用intel i3显卡的Thinkcentre,我注意到一些巨大的屏幕撕裂: http://s21.postimg.org/h6c42hic7/tear.jpg - 作为一个静止注意力有点困难。

我只是想知道是否有办法减少它,或者轻松启用垂直同步。如果没有,那么我可以在我的Windows 8应用程序端口中做些什么吗?

1 个答案:

答案 0 :(得分:2)

您使用的是requestAnimationFrame(RAF)吗? RAF将进行v-sync,但setTimeout / setInterval不会。

http://msdn.microsoft.com/library/windows/apps/hh920765

此外,由于30fps足以让您的用户看到平滑的动作,如何将60fps分成2个交替的部分:

  • 在一帧(无图纸)中“计算/更新”

  • 然后在下一帧中完成所有绘图。

然后,了解Chrome的时间线工具。这个出色的小工具可让您分析代码,以发现代码占用时间最多的地方。然后重构代码的这一部分以获得高性能。

[添加:有关requestAnimationFrame的更多有用详情]

Canvas不直接绘制到显示屏幕。相反,canvas将“渲染”到临时的屏幕外缓冲区。 “渲染”是指执行画布命令以在屏幕外缓冲区上绘制的过程。当下一次屏幕刷新发生时,此屏幕外缓冲区将快速绘制到实际显示屏幕。

在刷新期间在实际显示屏幕上绘制屏幕外缓冲区时,屏幕外渲染过程仅部分完成时会发生撕裂。

setInterval不会尝试使用屏幕刷新来协调渲染。因此,使用setInterval控制动画帧有时会产生撕裂。

requestAnimationFrame(RAF)尝试通过仅在屏幕刷新之间生成帧来修复撕裂(称为垂直同步的过程)。典型的显示器每秒刷新约60次(每16毫秒)。

使用requestAnimationFrame(RAF):

  • 如果当前帧未在下次刷新之前完全呈现,

  • RAF将延迟当前帧的绘制,直到下一次屏幕刷新。

  • 此延迟可减少撕裂。

所以对你而言,英国皇家空军可能会帮助你解决问题,但它也会带来另一个问题。

您必须决定如何处理物理处理:

  • 将其保存在一个单独的进程中,例如setInterval。
  • 将其移至requestAnimationFrame。
  • 将其移至web-workers(该工作在与UI线程分开的后台线程上完成)。

将物理保存在单独的setInterval中。

这有点像乘坐2列火车,每条腿只有1条腿 - 非常困难!您必须确保物理的所有方面始终处于有效状态,因为您永远不知道RAF何时会读取物理进行渲染。您可能必须创建物理变量的“缓冲区”,以便它们始终处于有效状态。

将物理场转移到RAF中:

如果你可以在刷新之间的16ms内计算物理和渲染,这个解决方案是理想的。如果不是,您的帧可能会延迟到下一个刷新周期。这导致30fps并不可怕,因为眼睛仍然以30fps感知清晰的运动。最糟糕的情况是延迟有时会发生,有时不会 - 然后你的动画可能会显得生涩。因此,关键是在刷新周期之间尽可能均匀地分布计算。

将物理学转移到网络工作者

Javascript是单线程的。 UI和计算都必须在这个单线程上运行。但是您可以使用在单独的线程上运行物理的Web工作者。这释放了UI线程,专注于渲染和绘制。但是你必须使用前景UI协调背景物理。

祝你好运:)