WebGL VS Canvas 2D 硬件加速

WebGL VS Canvas 2D hardware acceleration

这几天需要在canvas上画很多图。 canvas尺寸是800x600px,我有很多256x256px的图片(有些小)可以在上面画,这些小图片会在canvas上组成一个完整的图片。我有两种方法来实现这个。

首先,如果我使用 canvas 2D 上下文,即 context = canvas.getContext('2d'),那么我可以只使用 context.drawimage() 方法将每个图像放在 [=25] 的正确位置=].

另一种方式,我使用WebGL 在canvas 上绘制这些图像。这样,对于每个小图像,我都需要绘制一个矩形。矩形的大小与这个小图像相同。此外,矩形位于 canvas 的正确位置。然后我使用图像作为纹理来填充它。

然后,我比较了这两种方法的性能。他们俩的fps都会达到60,而且动画(当我用鼠标点击或移动时,canvas会重绘很多次)看起来很流畅。所以我比较了他们的CPU用法。我希望当我使用 WebGL 时,CPU 会用得更少,因为 GPU 会保证很多绘图工作。但结果是,CPU 用法看起来几乎相同。我尝试优化我的 WebGL 代码,我认为它已经足够好了。通过google,我发现Chrome等浏览器,Firefox默认会开启硬件加速。所以我尝试关闭硬件加速。那么第一种方法的CPU使用率就高了很多。所以,我的问题是,既然 canvas 2D 使用 GPU 加速,我是否有必要使用 WebGL 仅用于 2D 渲染? canvas 2D GPU 加速和 WebGL 有什么不同?他们都使用 GPU。也许还有其他方法可以降低第二种方法的 CPU 使用率?任何答案将不胜感激!

Canvas 2D 仍然比 WebGL 在更多地方得到支持,因此如果您不需要任何其他功能,那么使用 Canvas 2D 将意味着您的页面将在具有 canvas 但不是 WebGL(像旧的 android 设备)。当然,它在这些设备上会很慢,并且可能由于其他原因而失败,例如 运行 如果您有很多图像,内存不足。

理论上 WebGL 可以更快,因为 canvas 2d 的默认设置是保留绘图缓冲区,而对于 WebGL 则不是。这意味着如果您在 WebGL 上关闭抗锯齿功能,浏览器可以选择双倍缓冲。 canvas2d 做不到的事情。另一个优化是在 WebGL 中,您可以关闭 alpha,这意味着浏览器可以选择在将 WebGL 与页面合成时关闭混合,这同样是 canvas 2d 没有的选项。 (有计划能够关闭 canvas 2d 的 alpha,但截至 2017/6 年,它并未得到广泛支持)

但是,选项我的意思就是这个。由浏览器决定是否进行这些优化。

否则,如果您不选择这些优化,则 2 可能速度相同。我个人还没有发现这种情况。我尝试只用 canvas 2d 做一些 drawImage 的事情,但没有像我用 WebGL 那样获得平滑的帧率。这样做是没有意义的,但我认为浏览器内部发生了一些我没有意识到的事情。

我想这带来了最后的区别。 WebGL 是低级的并且是众所周知的。浏览器无法将其搞砸。或者换句话说,您可以 100% 掌控一切。

另一方面,对于 Canvas2D,由浏览器决定要做什么以及要进行哪些优化。它们可能会在每个版本中发生变化。我知道 Chrome 曾在 256x256 下的任何 canvas 都没有硬件加速。另一个例子是 canvas 在绘制图像时的作用。在 WebGL 中,您制作纹理。您决定着色器的复杂程度。在 Canvas 你不知道它在做什么。也许它正在使用支持所有各种 canvas globalCompositeOperation、遮罩和其他功能的复杂着色器。也许为了内存管理,它将图像分成多个块并将它们渲染成碎片。对于每个浏览器以及同一浏览器的每个版本,它决定做什么取决于该团队,而对于 WebGL,它几乎 100% 取决于您。他们在中间无法做太多事情来搞乱 WebGL。

仅供参考:这是 an article detailing how to write a WebGL version of the canvas2d drawImage function and it's followed by an article on how to implement the canvas2d matrix stack