经过多年关于顶点缓冲对象(VBO)的讨论,我终于决定尝试它们(我的东西通常不是性能关键,显然......)
我将在下面描述我的实验,但总而言之,我看到"简单"直接模式(glBegin()/ glEnd()),顶点数组(CPU端)和VBO(GPU端)之间无法区分性能渲染模式.我试图理解为什么会这样,并且在什么条件下我可以期待看到VBO明显优于他们原始(双关语)的祖先.
对于实验,我生成了一个具有大量点的(静态)3D高斯云.每个点都有与之关联的顶点和颜色信息.然后我在连续的帧中围绕云旋转相机,这是一种"轨道"行为.同样,这些点是静态的,只有眼睛移动(通过gluLookAt()).数据在任何渲染之前生成一次并存储在两个数组中以用于渲染循环.
对于直接渲染,整个数据集在单个glBegin()/ glEnd()块中呈现,其中包含一个循环,每个循环包含glColor3fv()和glVertex3fv().
对于顶点数组和VBO渲染,整个数据集使用单个glDrawArrays()调用进行渲染.
然后,我只需在紧凑的循环中运行一分钟左右,并使用高性能计时器测量平均FPS.
如上所述,我的台式机(XP x64,8GB RAM,512 MB Quadro 1700)和笔记本电脑(XP32,4GB RAM,256 MB Quadro NVS 110)的性能难以区分.然而,它确实按照预期的点数进行了扩展.显然,我也禁用了vsync.
笔记本电脑运行的具体结果(使用GL_POINTS渲染):
在glBegin()/ glEnd():
1K分 - > 603 FPS
10K分 - > 401 FPS
100K分 - > 97 FPS
1M点 - > 14 FPS
顶点阵列(CPU端):
1K分 - > 603 FPS
10K分 - > 402 FPS
100K分 - > 97 FPS
1M点 - > 14 FPS
顶点缓冲对象(GPU端):
1K分 - > 604 FPS
10K分 - > 399 FPS
100K分 - > 95 FPS
1M点 - > 14 FPS
我使用GL_TRIANGLE_STRIP渲染了相同的数据并且得到了类似的无法区分(尽管由于额外的光栅化而预期速度较慢).如果有人想要,我也可以发布这些数字..
是什么赋予了?
我需要做些什么才能实现VBO承诺的性能提升?
我错过了什么?
小智.. 27
优化3D渲染有很多因素.通常有4个瓶颈:
CPU(创建顶点,APU调用,其他一切)
总线(CPU < - > GPU传输)
顶点(固定函数管道执行时的顶点着色器)
像素(填充,片段着色器执行和rops)
您的测试结果是错误的,因为您在最大化顶点或像素吞吐量时拥有大量CPU(和总线).VBO用于降低CPU(更少的api调用,与CPU DMA传输并行).由于您不受CPU限制,因此它们不会给您带来任何好处.这是优化101.在游戏中,例如CPU变得很珍贵,因为它需要用于AI和物理等其他东西,而不仅仅是发出大量的api调用.很容易看出,将顶点数据(例如3个浮点数)直接写入内存指针比调用将3个浮点数写入内存的函数要快得多 - 至少可以保存调用的周期.
优化3D渲染有很多因素.通常有4个瓶颈:
CPU(创建顶点,APU调用,其他一切)
总线(CPU < - > GPU传输)
顶点(固定函数管道执行时的顶点着色器)
像素(填充,片段着色器执行和rops)
您的测试结果是错误的,因为您在最大化顶点或像素吞吐量时拥有大量CPU(和总线).VBO用于降低CPU(更少的api调用,与CPU DMA传输并行).由于您不受CPU限制,因此它们不会给您带来任何好处.这是优化101.在游戏中,例如CPU变得很珍贵,因为它需要用于AI和物理等其他东西,而不仅仅是发出大量的api调用.很容易看出,将顶点数据(例如3个浮点数)直接写入内存指针比调用将3个浮点数写入内存的函数要快得多 - 至少可以保存调用的周期.
可能缺少一些东西:
这是一个疯狂的猜测,但你的笔记本电脑的卡可能完全没有这种操作(即模仿它).
你(通过将数据复制到GPU的存储器glBufferData
(GL_ARRAY_BUFFER
与任一GL_STATIC_DRAW
或GL_DYNAMIC_DRAW
PARAM)或你在存储器使用指针主(非GPU)阵列?(需要每帧将它复制,因此很慢)
您是否将索引作为另一个缓冲区通过glBufferData
和GL_ELEMENT_ARRAY_BUFFER
params 传递?
如果完成这三件事,性能提升很大.对于Python(v/pyOpenGl),它在大于100个元素的数组上快大约1000倍,C++快5倍,但在阵列50k-10m顶点上.
以下是我对c ++(Core2Duo/8600GTS)的测试结果:
pts vbo glb/e ratio 100 3900 3900 1.00 1k 3800 3200 1.18 10k 3600 2700 1.33 100k 1500 400 3.75 1m 213 49 4.34 10m 24 5 4.80
因此,即使有10米的顶点,它也是正常的帧率,而对于glB/e,它是缓慢的.