为什么Canvas 2D上下文没有使用WebGL作为底层?

4

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

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

理论上,我认为在WebGL中可以模拟canvas 2D上下文中的所有内容,从而获得大量性能提升。那么为什么没有这样做呢?

我绝对不是在谈论更改任何语法或其他内容。我真的很喜欢2D上下文的简单性。但是为什么浏览器不在幕后执行教程所做的操作呢?

我知道WebGL并不完全支持所有浏览器,但我仍然认为如果可能的话,它可以作为常规2D上下文的后备方案来使用。

1个回答

14

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

如果您在WebGL中实现整个Canvas 2D规范,则很可能速度会类似。Canvas支持一些功能,例如使用图案进行绘制,使用渐变进行绘制,剪切路径等,可以添加所有这些特性到您的WebGL中实现的Canvas中,并且速度可能会类似。

WebGL之所以可以更快,是因为(a)您可以选择不实现不会使用的功能,(b)您可以进行优化,因为您只会使用某些功能。

作为一个简单的例子,在canvas中,您可以使用 drawImage(someImageElement, x, y)绘制图像。在WebGL中,您首先必须从图像创建纹理,然后使用纹理绘制,因此您需要手动管理该纹理。Canvas实际上也必须做同样的事情。它必须将图像加载到纹理中以便绘制它(假设它是基于GPU的,通常是这样的)。但是,它不知道您是否要再次绘制图像,因此它无法永久将该图像保留为纹理。最简单的实现方法是将图像复制到纹理中,进行绘制,然后删除纹理。我怀疑这不是canvas所做的,我猜它有一些图像所生成的纹理缓存。但是,关键在于,它的纹理管理是隐式的,而在WebGL中是显式的,您必须自己手动管理纹理。
另一个例子是绘制形状。在WebGL中,您通常在初始化时决定要绘制的形状,设置绘制所需的所有数据,然后在渲染时间使用您已经设置好的形状。在Canvas中,更常见的是即时绘制形状,这意味着每次要绘制形状时,您都需要使用moveTolineTo命令来绘制形状,这实际上是每次渲染时都要做所有的工作,而不像WebGL只在初始化时进行一次性的工作。正是这些差异导致了Canvas更容易,而WebGL更快。注意:一些人尝试在WebGL中实现Canvas2d,可以在这里这里找到相关内容。

这非常有道理。另外,感谢提供那些尝试实现它的例子。非常有趣! - Magnus Engdal
这是一个很棒的答案。 - Jeremy Chone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接