【问题标题】:Performance of WebGL and OpenGLWebGL 和 OpenGL 的性能
【发布时间】:2019-06-13 15:29:54
【问题描述】:

在过去的一个月里,我一直在搞乱 WebGL,发现如果我创建并绘制一个大的顶点缓冲区,它会导致低 FPS。有谁知道如果我在 C++ 中使用 OpenGL 是否相同?

这是使用的语言(WebGL 中的 JavaScript)还是 GPU 的瓶颈?

WebGL examples like this 表明您可以使用一个具有良好性能的缓冲区绘制 150,000 个立方体,但除此之外,我得到 FPS 下降。 OpenGL 也一样,还是可以处理更大的缓冲区?

基本上,我必须决定继续使用 WebGL 并尝试通过代码进行优化,或者 - 如果您告诉我 OpenGL 性能会更好并且它是语言速度瓶颈,请切换到 C++ 并使用 OpenGL。

【问题讨论】:

  • 这里的事实可能已经演变。只是为了在主要答案上添加颜色,Javascript 中的浮点运算比 C++ 慢 4-10 倍。但是,在您将内容加载到视频卡后,WebGL 和 OpenGL 的性能应该类似。 Chrome 似乎支持这一点,其他浏览器速度较慢。

标签: c++ opengl webgl


【解决方案1】:

如果您只有一个 drawArrays 调用,则调用本身在 OpenGL 和 WebGL 之间应该没有太大区别。但是,在 Javascript 中设置数据可能会慢很多,所以这真的取决于你的问题。如果您的大部分数据是静态的(景观、房间),WebGL 可能适合您。否则,在 JS 中设置数据可能对您的目的来说太慢了。这真的取决于你的问题。

附言如果您包含更多关于您正在尝试做的事情的详细信息,您可能会得到更详细/具体的答案。

【讨论】:

    【解决方案2】:

    有趣的是,我在 2000 年代初期使用运行非常流畅的旧 glVertex() 风格 API 编写了一个基于图块的游戏。我最近开始将它移植到 WebGL 和 glDrawArrays(),现在在我的现代 PC 上,它的速度至少快了 10 倍。

    原因似乎是我通过使用glDrawArrays() 来伪造呼叫去glBegin(GL_QUADS); glVertex()*4; glEnd();。在 WebGL 中使用 glDrawArrays() 绘制一个多边形要慢得多 比在 C++ 中使用 glVertex() 慢。

    我不知道这是为什么。也许是因为 javascript 很慢。也许是因为 javascript 中的一些上下文切换问题。无论如何,我只能做大约 500 个单多边形 glDrawArray() 调用,同时仍然获得 60 FPS。

    似乎每个人都通过在 GPU 上做尽可能多的事情来解决这个问题,并且每帧做的glDrawArray() 调用尽可能少。能否做到这一点取决于您要绘制的内容。在您链接的立方体示例中,它们可以在 GPU 上执行所有操作,包括移动立方体,这就是它速度快的原因。从本质上讲,他们作弊了——通常 WebGL 应用不会那样做。

    Google 进行了一次演讲,他们解释了这项技术(他们还在 GPU 上不切实际地计算了对象运动):https://www.youtube.com/watch?v=rfQ8rKGTVlg

    【讨论】:

    • 嗨,您看到的原因是因为 glDrawArray 比 glBegin 复杂得多。每次调用都必须支付一个固定的金额,这是相当高的。您应该做的是将所有多边形缓冲到一个 VAO 中,这样您就只能使用一个 glDrawArray。您拥有的多边形越多,glDraArray 和旧 gl immediate 之间的速度距离就越大,在由数百万个多边形组成的典型场景中,您会看到速度呈指数级增长。
    • 是的,这就是我所做的。不幸的是,流式传输到 VBO 也很慢 - 至少它似乎比我记得的 glBegin() 慢。如果您可以避免流式传输,那么它会非常快,但这取决于应用程序。
    【解决方案3】:

    由于使用了更新版本的 api,OpenGL 更加灵活和优化。 如果你说 OpenGL 速度更快、能力更强,这是真的,但这也取决于你的需求。

    如果您需要一个带有纹理的立方体网格,webGL 就足够了。但是,如果您打算构建具有大量顶点、后处理效果和不同渲染技术(以及置换类型、视差映射、逐顶点或曲面细分)的大型项目,那么 OpenGL 实际上可能是一个更好、更明智的选择。

    可以将缓冲区优化到单个调用,优化这些缓冲区的更新,但它当然有其局限性,是的,OpenGL 很可能无论如何都会表现得更好。

    要回答,这不是 语言 瓶颈,而是 api-version-used 瓶颈。 WebGL 基于 OpenGL ES,它有一些优点,但运行速度有点慢,并且它比纯 OpenGL 具有更多的代码处理抽象级别,这就是降低性能的原因 - 需要评估更多代码。

    如果您的项目不需要基于 Web 的解决方案,并且不关心支持哪些设备,那么 OpenGL 将是一个更好、更智能的选择。

    希望这会有所帮助。

    【讨论】:

    • 鉴于 WebGL 基于 OpenGL ES 2.0,因此已经使用现代(并且应该更高效)API桌面 OpenGL 版本使用,我宁愿说它与性能不同的 API 完全相反。 Javascript 更有可能不是实时计算的最佳选择。
    • 实际上 javascript 的数学运算速度相当快,并且接近已编译的 C 代码。我有一个在 WebGL/OpenGL 中构建的 3D 引擎,但我还没有发现明显的差异。我在加载/渲染性能和桌面 OpenGL/ES 之间测试了大约 256x256(hfz 地形)的巨大地形网格,并没有真正的区别。
    • javascript 的问题是函数调用开销和将数据移动到缓冲区(使用类型化/原生数组更快,但在 js 中不经常使用)在 C 中要高得多,因此必须最小化绘制调用。单个网格很棒,1000 个对象在 C 中很好,但在 js 中则不然。
    【解决方案4】:

    在相同的硬件上,WebGL 比同等的 OpenGL 慢得多,因为每次 WebGL 调用的监听频率都很高。

    在桌面 OpenGL 上,这种开销至少是有限的,如果仍然相对昂贵的话。

    但在 Chrome 等浏览器中,WebGL 不仅要求我们跨越 FFI 障碍来访问那些原生 OpenGL API 调用(这仍然会产生相同的开销),而且我们还需要安全检查以防止 GPU 被劫持进行计算。

    如果您正在查看类似glDraw* 的调用,每帧调用一次,这意味着我们正在讨论的调用可能(一个)数量级更少。更有理由选择instancing 之类的服务,这样通话次数会大大减少。

    【讨论】:

      猜你喜欢
      • 2014-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-15
      • 2018-02-15
      • 2011-12-30
      相关资源
      最近更新 更多