我正在尝试在OpenGL中为我的2D游戏绘制大量2D圆。它们大小相同且具有相同的纹理。许多精灵重叠。最快的方法是什么?
(这应该注意到,黑边缘只是由于圆形扩散而产生的。此屏幕截图后不久就被填充了。)
目前,我使用一对带纹理的三角形来制作每个圆。我在纹理的边缘周围使用透明度以使其看起来像一个圆。对于这个问题使用混合效果非常慢(并且无法进行z剔除,因为它们被渲染为深度缓冲区的正方形)。相反,我没有使用混合效果,而是让我的片段着色器丢弃任何alpha为0的片段。这有效,但意味着早期的z不可能(因为片段被丢弃)。
速度受到大量过度绘制和GPU填充率的限制。圆形的绘制顺序并不重要(只要在帧之间不改变,避免闪烁),因此我一直在尝试确保屏幕上的每个像素只能写入一次。
我尝试使用深度缓冲区来实现这一点。在每帧开始时,它被清除为1.0f。然后当绘制一个圆时,它会将深度缓冲区的该部分更改为0.0f。当应该绘制另一个圆时,由于新圆也具有0.0f的z值,所以它不会被绘制。这比较有效,应该减少需要绘制的像素数量。然而,奇怪的是,它并没有变快。我已经问过关于这种行为的问题(opengl depth buffer slow when points have same depth),建议是在使用相等的z值时,z剔除没有被加速。
相反,我必须为我的所有圆形分别指定从0开始的虚假z值。然后,当我使用glDrawArrays进行渲染并使用GL_LESS默认设置时,由于z剔除,我们可以正确地获得速度提升(尽管无法实现早期z,因为要丢弃片段以使圆形成为可能)。但是,这并不理想,因为我不得不添加大量与z相关的代码来制作一个简单的2D游戏(如果可能,不传递z值会更快)。然而,这是我目前找到的最快的方法。
最后,我尝试使用模板缓冲区,在这里我使用了
每帧都会将模板缓冲区重置为0。其思想是,在像素第一次绘制后,将其更改为模板缓冲区中的非零值。然后该像素不应再次绘制,从而减少了过度绘制的数量。然而,证明这并不比仅使用深度缓冲区或不使用任何缓冲区来绘制所有内容更快。
人们发现最快的方法是什么?
(这应该注意到,黑边缘只是由于圆形扩散而产生的。此屏幕截图后不久就被填充了。)
目前,我使用一对带纹理的三角形来制作每个圆。我在纹理的边缘周围使用透明度以使其看起来像一个圆。对于这个问题使用混合效果非常慢(并且无法进行z剔除,因为它们被渲染为深度缓冲区的正方形)。相反,我没有使用混合效果,而是让我的片段着色器丢弃任何alpha为0的片段。这有效,但意味着早期的z不可能(因为片段被丢弃)。
速度受到大量过度绘制和GPU填充率的限制。圆形的绘制顺序并不重要(只要在帧之间不改变,避免闪烁),因此我一直在尝试确保屏幕上的每个像素只能写入一次。
我尝试使用深度缓冲区来实现这一点。在每帧开始时,它被清除为1.0f。然后当绘制一个圆时,它会将深度缓冲区的该部分更改为0.0f。当应该绘制另一个圆时,由于新圆也具有0.0f的z值,所以它不会被绘制。这比较有效,应该减少需要绘制的像素数量。然而,奇怪的是,它并没有变快。我已经问过关于这种行为的问题(opengl depth buffer slow when points have same depth),建议是在使用相等的z值时,z剔除没有被加速。
相反,我必须为我的所有圆形分别指定从0开始的虚假z值。然后,当我使用glDrawArrays进行渲染并使用GL_LESS默认设置时,由于z剔除,我们可以正确地获得速度提升(尽管无法实现早期z,因为要丢弃片段以使圆形成为可能)。但是,这并不理想,因为我不得不添加大量与z相关的代码来制作一个简单的2D游戏(如果可能,不传递z值会更快)。然而,这是我目前找到的最快的方法。
最后,我尝试使用模板缓冲区,在这里我使用了
glStencilFunc(GL_EQUAL, 0, 1);
glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
每帧都会将模板缓冲区重置为0。其思想是,在像素第一次绘制后,将其更改为模板缓冲区中的非零值。然后该像素不应再次绘制,从而减少了过度绘制的数量。然而,证明这并不比仅使用深度缓冲区或不使用任何缓冲区来绘制所有内容更快。
人们发现最快的方法是什么?