我正在使用opengl在Android上开发一款游戏,并且遇到了一些性能问题。
比方说,我想绘制一个部分充满草“灌木丛”的背景。灌木有不同的x,y,z,不同的尺寸等等(每个灌木都是2D精灵),并且可能部分地相互隐藏(我使用透视相机)。如果那些精灵很大(即四边形尺寸,而不是纹理尺寸/分辨率),我会遇到很大的性能问题:
如果我使用经典的正反面绘制(以避免透支),我发现自己因为(我认为)alpha测试而遇到问题。即使灌木丛只有不透明和完全透明的像素(没有部分透明度),如果我使用正确的alpha测试比较(GL_EQUAL 1),性能也很差,因为很多像素必须进行alpha测试(如果我理解的话)
如果我使用禁用alpha测试的前后显示器,我也会失去很多性能(但这次是因为过度绘制问题),即使禁用深度缓冲区写入(不确定它是否有效)深度测试被禁用)。
如果在没有alpha测试的情况下前后使用我有很好的表现,但当然精灵抠图已经完全消失,这真的很糟糕。
所有的灌木丛都有相同的纹理,我使用16位颜色,mip贴图,几何批处理,剔除面孔,没有着色器等等。所有我能想到的提高性能(在其他情况下都不错),纹理压缩除外。我甚至过滤精灵,以避免“显示”屏幕上的那些。我还尝试了一些“暴力优化”用于测试目的,例如使纹理完全不透明,大幅降低纹理分辨率,禁用混合等,但除了alpha测试删除之外,没有什么是出色的性能。
我想知道我是否忘了这里的东西以帮助表演。回到前面创建透支,因为alpha测试从前到后很慢(而且我不希望我的灌木成为“方形”图像所以我不能禁用alpha测试)。如果我创建更小的精灵,表现要好得多(即使有更多的精灵),但这只是一种解决方法。
总结一下,如何在不损失性能的情况下显示需要剪切的重叠大四边形?
PS:我正在测试一个nexus。
PS2 :一些优化建议不要创建四边形,但是几何图形更适合纹理,但它似乎是一个非常繁琐的过程,并且我认为它对我帮助不大。
答案 0 :(得分:1)
从前到后绘制通常是一个好处,因为早期-z:在进行纹理提取或着色之前,硬件可以在光栅化之后立即进行深度测试。通过前后排序,大多数片段都无法通过深度测试,您可以节省大量纹理带宽,着色吞吐量和zbuffer-write带宽。
但是阿尔法测试打破了这一点。如果一个片段通过深度测试,它仍然可能被alpha测试杀死,所以zwrite直到纹理/着色后才会发生。大多数可以做早期z的硬件仍然必须在管道中的同一点进行深度测试,因为它使用zwrite,因此使用alpha测试,你最终会在纹理和着色后进行ztest + zwrite。因此,前后排序只能为您节省zwrite带宽,而不是其他任何内容。
我认为你有两个选择,如果你真的想要大幅度重叠的精灵:
(a)只为精灵使用两个或三个不同的Z值。使用混合(和alpha测试,如果有帮助)将它们从前面拉到前面。图层中没有重叠:您可以在原始资源中预渲染每个图层,也可以在运行时预渲染一次,然后只需左右移动。
(b)如果您的精灵有一个由半透明边框包围的大的不透明区域,您可以在没有alpha测试的第一个过程中绘制不透明区域,然后将边框绘制为单独的过程。这将减少经过alpha测试的片段的数量。