HTML/Canvas - drawImage 性能与另一个画布

Posted

技术标签:

【中文标题】HTML/Canvas - drawImage 性能与另一个画布【英文标题】:HTML/Canvas - drawImage performance with another canvas 【发布时间】:2011-04-27 14:15:59 【问题描述】:

我正在开发一款游戏,但在使用 drawImage 将一个画布绘制到另一个画布上时遇到了一些性能问题。根据 Chrome 的 Profiler,我将 60% 的时间花在这个 drawImage 调用上,而 10% 的时间花在它上面的 clearRect...

源画布现在大约是 3000x3000(我会说这非常小),目标画布是 1024x768。

我想这不是画所有的瓷砖;墙壁等等等等每个循环(给我大约15fps),将它们全部绘制到屏幕外画布上然后将其绘制到我的主画布上,然后在顶部绘制实体等可能会更快.这给了我大约 30 fps 但......这是我将通过软件渲染获得的最佳效果吗?

我的渲染循环基本上是:

ctx.clearRect(0, 0, 1024, 768);

ctx.beginPath();
ctx.drawImage(map, cam.position.i, cam.position.j, 1024, 768, 0, 0, 1024, 768);
ctx.closePath();

ctx.save();
ctx.translate(-cam.position.i, -cam.position.j);
// draw entities, etc.
ctx.restore();

除了开始使用 WebGL(利用其硬件加速)或等待供应商为 2d 上下文实施硬件加速之外,我真的想不出该怎么做。不过,我宁愿不这样做,所以任何意见都将不胜感激。

【问题讨论】:

我不确定 beginPath 和 closePath 是否适用于 drawImage。 啊,我一直将它们用于带有 lineTo/moveTo 和 drawImage 的路径。我刚刚删除了它们,帧速率大致相同,但还是谢谢。 3000x3000 是巨大的,即使是 1024x768 的软件渲染也已经很慢了,或者它耗尽了它可以获得的所有 CPU,根据我的经验,在硬件加速完全到达之前你无能为力。不过,您可能会考虑对基于图块的游戏使用基于 html 的方法。 【参考方案1】:

哇,那是一个很大的屏幕外画布。仅用于缓冲区的存储空间约为 36MB。

我很想使用较小的屏幕外图块,例如1024x124 并在主画布上绘制可见的。为了节省内存,您只能最初创建可见图块,然后在它们变得可见时生成其他图块。 (你可以处理掉,甚至更好地回收那些不再可见的)。

我不相信建议您使用 putImageData 的答案会提供更好的性能,因为这里提问者的经验表明:why-is-putimagedata-so-slow

【讨论】:

【参考方案2】:

为每个“精灵”使用 getImageData 并在 javascript 中保留对 imageData 数组的引用并使用 putImageData 渲染到目标画布可能会更快。

您仍然可以使用不可见的源画布和每个图块/精灵上的 getImageData 来渲染您的精灵。它会使用更多内存,但可能比具有源画布和目标画布的 drawImage 更快。

【讨论】:

以上是关于HTML/Canvas - drawImage 性能与另一个画布的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 Canvas drawImage 比例错误 iOS

HTML5 Canvas drawImage 比例bug iOS

HTML5 Canvas DrawImage Safari 12.0 错误(在 iOS 12.1/Mac OS Mojave 上测试)

来自视频的 HTML5 Canvas drawImage 在第一次绘制时未显示

从 HTML Canvas 捕获图像的最快方法

HTML Canvas 不显示图像