【问题标题】:Why isn't canvas 2D context using WebGL under the hood?为什么画布 2D 上下文不使用 WebGL?
【发布时间】:2020-05-09 15:07:15
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: canvas webgl


    【解决方案1】:

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

    如果您在 WebGL 中实现整个 Canvas 2D 规范,可能会达到类似的速度。 Canvas 支持使用patterns 绘图、使用gradientsclipping paths 绘图、任意宽度、末端、连接等的线条……将所有这些功能添加到用WebGL 实现的Canvas 中,它可能具有相似的速度。

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

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

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

    这些差异加起来使得 canvas 更简单,webgl 更快。

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

    【讨论】:

    • 这很有意义。另外,感谢人们尝试实施它的示例。很有趣!
    • 这是一个很好的答案。
    猜你喜欢
    • 1970-01-01
    • 2020-11-17
    • 2019-05-07
    • 2012-01-09
    • 2023-03-27
    • 1970-01-01
    • 2016-12-25
    • 2011-04-22
    • 2011-02-20
    相关资源
    最近更新 更多