【发布时间】:2013-02-04 10:28:59
【问题描述】:
我正在尝试在 opengl 中为我的 2d 游戏绘制大量 2d 圆圈。它们的大小相同,质地相同。许多精灵重叠。最快的方法是什么?
an example of the kind of effect I'm making http://img805.imageshack.us/img805/6379/circles.png
(需要注意的是,黑边只是由于圆圈的扩大爆炸造成的。截屏后不久就被填充了。
目前我正在使用一对带纹理的三角形来制作每个圆圈。我在纹理边缘周围有透明度,以使其看起来像一个圆圈。事实证明,为此使用混合非常慢(并且 z 剔除是不可能的,因为它们被渲染为深度缓冲区的正方形)。相反,我没有使用混合,而是让我的片段着色器丢弃任何 alpha 为 0 的片段。这可行,但是这意味着早期 z 是不可能的(因为片段被丢弃)。
速度受到大量透支和 GPU 填充率的限制。圆圈的绘制顺序并不重要(只要它不会在产生闪烁的帧之间发生变化),所以我一直在努力确保屏幕上的每个像素只能写入一次。
我尝试使用深度缓冲区。在每一帧开始时,它被清除为 1.0f。然后,当绘制一个圆圈时,它会将深度缓冲区的那部分更改为 0.0f。当通常在那里绘制另一个圆时,它不是因为新圆的 z 也为 0.0f。这不小于深度缓冲区中当前存在的 0.0f,因此它不会被绘制。这有效,并且应该减少必须绘制的像素数量。然而;奇怪的是它并没有更快。我已经问过一个关于这种行为的问题 (opengl depth buffer slow when points have same depth),建议是使用相等的 z 值时 z 剔除没有被加速。
相反,我必须将我所有的圈子从 0 向上分开的虚假 z 值。然后,当我使用 glDrawArrays 和默认值 GL_LESS 进行渲染时,由于 z 剔除,我们正确地获得了速度提升(尽管早期 z 是不可能的,因为碎片被丢弃以使圆圈成为可能)。然而,这并不理想,因为我不得不为 2d 游戏添加大量与 z 相关的代码,而这根本不需要它(如果可能的话,不传递 z 值会更快)。然而,这是我目前找到的最快的方法。
最后我尝试了使用模板缓冲区,这里我使用了
glStencilFunc(GL_EQUAL, 0, 1);
glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
模板缓冲区每帧重置为 0。这个想法是在一个像素被绘制到第一次之后。然后在模板缓冲区中将其更改为非零。然后不应再次绘制该像素,从而减少透支量。然而,事实证明,这并不比仅在没有模板缓冲区或深度缓冲区的情况下绘制所有内容快。
人们发现写我正在尝试的最快方法是什么?
【问题讨论】:
-
你是单批画的吗?
-
是的,只有一个 glDrawArrays(GL_TRIANGLES, 0, 100001*(2*3));每帧绘制所有这些。
-
hmm 我预计会有相当好的结果 - 窗口越小越快?
-
是的。它要快得多。
标签: performance opengl gpu geometry particles