WebGL和OpenGL的性能

Performance of WebGL and OpenGL

本文关键字:性能 OpenGL WebGL      更新时间:2023-10-16

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

这是所用语言(WebGL中的JavaScript)或GPU的瓶颈吗?

像这样的WebGL示例表明,您可以使用一个性能良好的缓冲区绘制150000个立方体,但除此之外,我还会得到FPS下降。OpenGL也是如此,还是能够处理更大的缓冲区?

基本上,我必须决定继续使用WebGL,并尝试通过代码进行优化,或者——如果你告诉我OpenGL会表现得更好,而且这是语言速度的瓶颈,那么切换到C++并使用OpenGL。

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

附言:如果你把你想做的事情的更多细节包括在内,你可能会得到更详细/具体的答案。

有趣的是,我在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应用程序不会是这样的。

谷歌在一次演讲中解释了这项技术(他们还不切实际地计算了GPU上的物体运动):https://www.youtube.com/watch?v=rfQ8rKGTVlg

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

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

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

如果你看到的是像glDraw*调用这样的调用,它们是按帧调用的,这意味着我们谈论的调用可能会减少一个数量级。更有理由选择实例化之类的方法,因为实例化可以大幅减少调用次数。

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

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

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

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

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

希望这能有所帮助。