首页 > 解决方案 > 为什么画布 2D 上下文不使用 WebGL?

问题描述

我经常使用画布 2D 上下文,最近也开始学习一些 WebGL。

当我在编写有关如何context.drawImage()在 WebGL 中从 2D 上下文实现的教程时,我想到了标题中的问题。结果是类似的东西context.drawImage()(至少非常接近),但速度要快得多,因为它使用了 WebGL。

理论上,我相信画布 2D 上下文中的所有内容都可以在 WebGL 中进行模拟,从而带来巨大的性能提升。那为什么不是呢?

我绝对不是在谈论改变任何语法或任何东西。我真的很喜欢 2D 上下文的简单性。但是为什么浏览器不做那个教程在幕后做的事情呢?

我知道 WebGL 并非在所有地方都得到完全支持,但我仍然认为如果可能的话,可以使用它,将常规 2D 上下文作为后备。

标签: canvaswebgl

解决方案


Canvas2D 使用与 WebGL 基本相同的 API 在底层使用 GPU。

如果您在 WebGL 中实现整个 Canvas 2D 规范,可能会达到类似的速度。Canvas 支持诸如使用图案绘制、使用渐变绘制、剪切路径、任意宽度的线条、端点、连接等...将所有这些功能添加到您在 WebGL 中实现的 Canvas 中,它可能具有相似的速度。

WebGL可以更快的原因是(a)因为您可以选择不实现您不会使用的功能,以及(b)因为您可以优化知道您只会使用某些功能。

举个简单的例子,在画布中你可以用drawImage(someImageElement, x, y). 在 WebGL 中,您首先必须从图像创建纹理,然后使用纹理进行绘制,以便手动管理该纹理。画布实际上必须做同样的事情。它必须将图像加载到纹理中才能绘制它(假设它通常是基于 GPU 的画布)。但是,它不知道您是否要再次绘制图像,因此它无法将该图像永远保留为纹理。最简单的实现是将图像复制到纹理,绘制,然后删除纹理。我怀疑这就是画布的作用,我猜它有一些由图像制成的纹理缓存。但是,关键是,它对纹理的管理是隐式的,而在 WebGL 中它是显式的,您必须自己手动管理纹理。

另一个例子是绘制形状。在 WebGL 中,您通常决定在初始化时绘制哪些形状,设置绘制它们所需的所有数据,然后在渲染时您只需使用已设置的形状。在 Canvas 中,动态绘制形状更常见,这意味着每次您想要绘制您使用的形状moveTo和绘制形状的lineTo命令时,每次渲染时有效地完成所有工作,而不是像 WebGL 那样只在初始化时间。

就像那些加起来画布更容易和 webgl 更快的差异一样。

注意:有些人在这里这里尝试在 WebGL 中实现 canvas2d


推荐阅读