【发布时间】:2011-03-15 06:00:29
【问题描述】:
这可能已经被问了一遍又一遍,但我找不到任何有用的东西,所以又来了......
在我的应用程序中,我需要渲染一个相当大的网格(几百万个或更多三角形),但我在从中获得不错的帧速率时遇到了一些问题。 CPU 几乎处于空闲状态,所以我肯定受 GPU 限制。更改分辨率不会影响性能,因此它不受片段或光栅限制。
网格是动态的(但在本地是静态的),因此我无法将整个内容存储在视频卡中并一次调用即可渲染它。出于应用程序特定的原因,数据存储为叶子中带有体素的八叉树,这意味着我基本上可以免费进行视锥体剔除。顶点数据由坐标、法线和颜色组成 - 不使用纹理或着色器。
我的第一种方法是使用一个大的STREAM_DRAW VBO 从内存中渲染所有内容,结果证明这太慢了。我最初的想法是我可能使总线负担过重(每帧推约 150 MiB),所以我实现了一个缓存方案,该方案存储了最近用于在显卡上以静态 VBO 呈现对象的几何图形,每个 VBO 存储几个100 KiB 到几个 MiB 的数据(每个 VBO 存储更多会产生更多的缓存抖动,所以这里需要权衡)。下图是数据外观的示例,其中所有红色的内容都是从缓存的 VBO 中绘制的。
(来源:sourceforge.net)
如下面的数字所示,我没有看到使用缓存时性能的显着提升。对于大约 100 万个三角形的完全静态网格,我得到以下帧速率:
- 无缓存:1.95 Hz
- 使用顶点数组进行缓存:2.0 Hz(>75% 的网格被缓存)
- 使用
STATIC_DRAWVBO 进行缓存:2.4 Hz
所以我的问题是如何加快速度?即:
- 推荐的顶点格式是什么以获得良好的性能?我使用交错存储,位置和法线为
GL_FLOAT和GL_UNSIGNED_BYTE用于颜色,使用一个填充字节来获得 4 字节对齐(总共 28 个字节/顶点)。 - 是否对我的所有盒子使用相同的法线缓冲区可能会有所帮助(所有盒子都是轴对齐的,因此我可以分配最大缓存条目大小的普通缓冲区并将其用于所有盒子)。
- 我如何知道管道的哪一部分是瓶颈?我没有出色的显卡(带有开源 Linux 驱动程序的英特尔 GM965),所以我可能会达到它的极限。我可以从典型硬件(2-3 年的集成显卡、现代集成显卡、现代独立显卡)中获得多少吞吐量?
- 有关如何解决此问题、陷阱等的任何其他提示。
我对建议 LOD(我已经测试过)、供应商特定提示或使用 1.5 之后的任何 OpenGL 功能的答案不感兴趣。
【问题讨论】:
-
你的图元只包含在轴对齐的盒子里吗?
-
@Stringer Bell:是的(但不一定与世界轴对齐)。
-
我不确定,但我猜你达到了显卡限制。我用谷歌搜索了一下,似乎英特尔 GM965 的性能相当低,尤其是在游戏方面。 (您的不是游戏,但渲染起来似乎相当“困难”)。 Nvidia有一个列表,他们的卡可以渲染多少个三角形/秒-也许你可以用这个列表对你的卡进行分类,以找出“理论”限制。
-
您每帧进行多少次绘制调用?
-
@Andy J Buchanan:视情况而定,但在 50-150 左右。我可以调整这个,但到目前为止,允许更小的缓存条目(=> 更多的绘制调用)似乎提供了最好的吞吐量。
标签: opengl performance