1

我正在使用 opengl 在 android 上开发游戏,但遇到了一点性能问题。

例如,假设我想绘制一个部分填充草“灌木”的背景。灌木有不同的 x、y、z、不同的大小等等(每个灌木都是 2D 精灵),并且可能会部分地相互隐藏(我使用透视相机)。如果这些精灵很大(即四边形大小,而不是纹理大小/分辨率),我会遇到很大的性能问题:

  • 如果我使用经典的从前到后绘制(以避免过度绘制),我发现自己因为(我认为)alpha 测试而遇到问题。即使灌木丛只有不透明和完全透明的像素(没有部分透明),并且如果我使用正确的 alpha 测试比较(GL_EQUAL 1),性能也很差,因为很多像素必须经过 alpha 测试(如果我理解正确的话) .

  • 如果我使用禁用 alpha 测试的后到前显示器,我也会失去很多性能(但这次是因为过度绘制问题),即使禁用深度缓冲区写入(如果深度测试被禁用,不确定它是否会做任何事情)方法)。

如果在没有 alpha 测试的情况下从前到后使用,我会有很好的表现,但当然精灵切割完全消失了,这真的很糟糕。

所有灌木都具有相同的纹理,我使用 16 位颜色、mip 映射、几何批处理、剔除面、无着色器等。所有我能想到的提高性能(在其他情况下也不错),除了纹理压缩. 我什至过滤精灵以避免“显示”屏幕之外的精灵。为了测试目的,我还尝试了一些“暴力优化”,例如使纹理完全不透明、大大降低纹理分辨率、禁用混合等,但除了 alpha 测试删除之外,没有什么是出色的性能方面的。

我想知道我是否在这里忘记了一些有助于表演的东西。从前到后会产生透支,由于 alpha 测试,从前到后很慢(而且我不希望我的灌木丛是“方形”图像,所以我不能禁用 alpha 测试)。如果我创建更小的精灵,性能会好得多(即使有更多的精灵),但这只是一种解决方法。

总而言之,如何在不损失性能的情况下显示重叠的需要剪切的大四边形?

PS:我正在测试一个nexus。

PS2:一些优化建议不要创建四边形,而是创建更“适合”纹理的几何图形,但这似乎是一个非常乏味的过程,我认为对我没有多大帮助。

4

1 回答 1

1

由于 early-z,从前到后绘制通常是一个好处:硬件可以在光栅化之后立即进行深度测试,然后再进行纹理提取或着色。使用从前到后的排序,大多数片段都无法通过深度测试,并且可以节省大量纹理带宽、着色吞吐量和 zbuffer-write 带宽。

但是 alpha 测试打破了这一点。如果一个片段通过了深度测试,它仍然可能被 alpha 测试杀死,所以 zwrite 直到纹理/着色之后才能发生。大多数可以做 early-z 的硬件仍然必须在管​​道中的同一点做深度测试,因为它做 zwrite,所以使用 alpha 测试你最终会在纹理和着色之后做 ztest + zwrite。因此,从前到后的排序只会为您节省 zwrite 带宽,没有别的。

如果您真的想要显着重叠的大型精灵,我认为您有两种选择:

(a) 只为您的精灵使用两个或三个不同的 Z 值。通过混合(和 alpha 测试,如果有帮助)将它们从后到前绘制。图层内没有重叠:您可以在原始资源中或在运行时预渲染每个图层,然后左右移动。

(b) 如果你的精灵有大的不透明区域被半透明的边框包围,你可以在没有 alpha 测试的第一遍中绘制不透明区域,然后将边框作为单独的遍绘制。这将减少经过 alpha 测试的片段的数量。

于 2013-05-15T22:40:36.743 回答