这个问题可能一而再、再而三地被问到,但我没找到什么有用的信息,所以我再次提出它...
在我的应用程序中,我需要呈现一个相当大的网格(几百万个三角形或更多),但是我在获取良好的帧速率方面遇到了一些问题。CPU几乎处于空闲状态,因此我明显受限于GPU。更改分辨率不影响性能,因此它不是片段或栅格化限制。
该网格是动态的(但局部静态),因此无法将整个网格存储在视频卡中,并使用单个调用进行呈现。由于应用程序特定原因,数据存储为八叉树,并在叶子节点上使用体素,这意味着我基本上可以免费获得视锥体裁剪。顶点数据包括坐标,法线和颜色-不使用纹理或着色器。
我的第一种方法是使用一个大的STREAM_DRAW
VBO从内存中呈现所有内容,结果速度太慢。我的初始想法是我可能过度使用总线(每帧推送约150 MiB),因此我实施了一个缓存方案,将最近用于呈现对象的几何体存储在图形卡的静态VBO中,每个VBO存储几百KiB到几MiB的数据(存储更多每个VBO会导致更多的缓存抖动,因此在此处存在权衡)。下面的图片是数据外观的示例,在这个示例中,所有红色的东西都是从缓存的VBO中绘制的。
(来源:sourceforge.net)
如下所示的数字表明,当使用缓存时,我没有看到性能显著提高。对于大约100万个三角形的完全静态网格,我得到以下帧速率:
- 不使用缓存:1.95 Hz
- 使用顶点数组进行缓存:2.0 Hz(> 75%的网格已被缓存)
- 使用
STATIC_DRAW
VBO进行缓存:2.4赫兹
我的问题是如何加速?即:
- 什么是建议的顶点格式以获得良好的性能?我使用交替存储,位置和法线为
GL_FLOAT
,颜色为GL_UNSIGNED_BYTE
,其中一个填充字节以获得4字节对齐(总共28字节/顶点)。 - 是否为所有的盒子都使用相同的法线缓冲区可能会有帮助(所有的盒子都是轴对齐的,所以我可以分配一个最大缓存条目大小的法线缓冲区,并将其用于它们所有的盒子)。
- 如何知道管道的哪个部分是瓶颈?我的显卡不是很好(Intel GM965与开源Linux驱动程序),因此我可能达到了它的极限。从典型硬件(2-3年前的集成图形,现代集成图形,现代离散图形)可以期望多少吞吐量?
- 您如何处理此问题的任何其他提示,陷阱等。
我不感兴趣的答案包括LOD(我已经测试过了),供应商特定的提示或使用OpenGL功能,来自任何晚于1.5的版本。