Html 画布 1600x1200 屏幕撕裂 [英] Html canvas 1600x1200 screen tearing

查看:32
本文介绍了Html 画布 1600x1200 屏幕撕裂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到过一些关于这个问题的问题,但他们都已经三年多了,通常最后都会说还没有太多解决办法,所以我想知道是否有任何改变.

I've seen a couple of questions asking about this, but they're all over three years old and usually end by saying theres not much of a way around it yet, so im wondering if anything's changed.

我目前正在开发一款游戏,该游戏使用每秒发生 60 次的间隔绘制到画布上.它在我的 iphone 和 PC 上运行良好,但我的 iphone 和 PC 有一个不错的图形卡,但我现在正在带有 intel i3 图形的 Thinkcentre 上尝试它,我注意到一些巨大的屏幕撕裂:http://s21.postimg.org/h6c42hic7/tear.jpg - 有点作为静止图像更难注意到.

I'm currently working on a game that draws onto a canvas using an interval that happens 60 times a second. It works great on my iphone and PC, which has a faily decent graphics card, but I'm now trying it on a Thinkcentre with intel i3 graphics, and I notice some huge screen tearing: http://s21.postimg.org/h6c42hic7/tear.jpg - it's a little harder to notice as a still.

我只是想知道是否有任何方法可以减少这种情况,或者轻松启用垂直同步.如果没有,我可以在游戏的 Windows 8 应用程序端口中执行某些操作吗?

I was just wondering if there's any way to reduce that, or to easily enable vertical sync. If there isnt, is there somethingthat I could do in my windows 8 app port of the game?

推荐答案

您在使用 requestAnimationFrame (RAF) 吗?RAF 会进行垂直同步,但 setTimeout/setInterval 不会.

Are you using requestAnimationFrame (RAF)? RAF will v-sync but setTimeout/setInterval will not.

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

此外,由于 30fps 足以让您的用户看到流畅的运动,那么将 60fps 分成 2 个交替部分如何:

Also, since 30fps is adequate for your users to see smooth motion, how about splitting your 60fps into 2 alternating parts:

  • 在一帧内计算/更新"(无绘图)

  • "calculate/update" during one frame (no drawing)

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

and then do all the drawing in the next frame.

此外,了解 Chrome 的时间轴工具.这个很棒的小工具可让您分析代码以发现代码花费最多时间的地方.然后重构该部分代码以获得高性能.

And, get to know Chrome's Timeline tool. This great little tool lets you analyze your code to discover where your code is taking the most time. Then refactor that part of your code for high performance.

[附加:关于 requestAnimationFrame 的更多有用细节]

Canvas 不会直接绘制到显示屏上.相反,画布渲染"到临时的屏幕外缓冲区.渲染"是指执行画布命令以在屏幕外缓冲区上绘制的过程.这个离屏缓冲区会在下一次屏幕刷新发生时快速绘制到实际显示屏幕.

Canvas does not paint directly to the display screen. Instead, canvas "renders" to a temporary offscreen buffer. "Rendering" means the process of executing canvas commands to draw on the offscreen buffer. This offscreen buffer will be quickly drawn to the actual display screen when the next screen refresh occurs.

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

Tearing occurs when the offscreen rendering process is only partially complete when the offscreen buffer is drawn on the actual display screen during refresh.

setInterval 不会尝试协调渲染与屏幕刷新.所以,使用setInterval来控制动画帧偶尔会产生撕裂.

setInterval does not attempt to coordinate rendering with screen refresh. So, using setInterval to control animation frames will occasionally produce tearing .

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

requestAnimationFrame (RAF) attempts to fix tearing by generating frames only between screen refreshes (a process called vertical synching). The typical display refreshes about 60 times per second (that’s every 16 milliseconds).

使用 requestAnimationFrame (RAF):

  • 如果当前帧在下次刷新前没有完全渲染,

  • If the current frame is not fully rendered before the next refresh,

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

RAF will delay the painting of the current frame until the next screen refresh.

这种延迟减少了撕裂.

因此,对于您而言,RAF 可能会帮助您解决撕裂问题,但同时也会带来另一个问题.

So for you, RAF will likely help your tearing problem, but it also introduces another problem.

你必须决定如何处理你的物理处理:

You must decide how to handle your physics processing:

  • 将它保存在一个单独的进程中——比如 setInterval.
  • 将其移至 requestAnimationFrame.
  • 将其移至网络工作者(该工作在与 UI 线程分离的后台线程上完成).

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

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

This is a bit like riding 2 trains with 1 leg on each—very difficult! You must be sure that all aspects of the physics are always in a valid state because you never know when RAF will read the physics to do rendering. You will probably have to create a "buffer" of your physics variables so they always are in a valid state.

将物理转移到英国皇家空军:

如果您可以在刷新之间的 16 毫秒内计算物理和渲染,则此解决方案是理想的.如果没有,您的帧可能会延迟到下一个刷新周期.这导致 30fps,这并不可怕,因为眼睛仍然能以 30fps 的速度感知到清晰的运动.最坏的情况是有时会发生延迟,有时不会发生 — 那么您的动画可能会显得生涩.所以这里的关键是在刷新周期之间尽可能均匀地分布计算.

If you can both calculate physics and render within the 16ms between refreshes, this solution is ideal. If not, your frame may be delayed until the next refresh cycle. This results in 30fps which is not terrible since the eye still perceives lucid motion at 30fps. Worst case is that the delay sometimes occurs and sometimes not—then your animation may appear jerky. So the key here is to spread the calculations as evenly as possible between refresh cycles.

将物理转移到网络工作者

Javascript 是单线程的.UI 和计算都必须在这个单线程上运行.但是您可以使用在单独线程上运行物理的网络工作者.这释放了 UI 线程以专注于渲染和绘画.但是你必须将背景物理与前景 UI 协调起来.

Javascript is single-threaded. Both the UI and calculations must run on this single thread. But you can use web workers which run physics on a separate thread. This frees up the UI thread to concentrate on rendering and painting. But you must coordinate the background physics with the foreground UI.

祝你游戏好运:)

这篇关于Html 画布 1600x1200 屏幕撕裂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆