如何处理由“平方”纹理引起的纹理失真,以及与mipmapping的交互?

时间:2012-03-26 20:06:46

标签: ios opengl-es opengl-es-2.0 mipmaps pvrtc

假设我的纹理自然不是正方形(例如,长宽比为4:1的照片纹理)。并且假设我想使用PVRTC压缩在iOS设备上显示此纹理,这需要纹理是方形的。如果我按比例缩放纹理以使其在压缩过程中呈正方形,则从远处查看纹理时,结果会非常模糊。

我相信这是由mipmapping造成的。由于mipmap过滤器会看到新的较大拉伸尺寸,因此它使用它来选择低mip级别,这实际上是不正确的,因为这些像素只是拉伸到那个大小。如果它查看另一个维度,它将选择更高分辨率的mip级别。

这一理论在某种程度上得到了证实,即如果我将纹理保留为不必为正方形的格式,则mipmap版本看起来只是花花公子。

有一个LOD Bias参数,但文档说这适用于两个维度。似乎所要求的是一种偏向LOD的方法,但仅限于一个维度(即,将其偏向于按比例放大的纹理维度中的更高分辨率)。

除了砍掉几何图形以允许使用原始纹理的方形子集(这是不可行的,给我们的生产管道),有没有人有他们用来处理这个问题的任何聪明的黑客?

1 个答案:

答案 0 :(得分:0)

在我看来,你有几个选择,取决于你可以做什么,比如顶点UVs。

[嗯刚刚意识到在下面我假设V坐标从顶部到底部运行......你需要允许我老去学校:-)]

首先想到的是采用4N * N(X * Y)源纹理并垂直重复4x以产生4N * 4N纹理,然后将模型上的V坐标调整为1 /他们当前的4个值。对于内存而言,这不会为您节省太多(因为它实际上意味着4bpp PVRTC变大了4倍)但它仍然仍然节省带宽和缓存空间,因为其他部分纹理将无法访问。 MIP映射也可以一直工作到1x1纹理。

或者,如果你想节省一些空间并且你有一对4N * N纹理,你可以尝试将它们拼凑成一个“4N * 4N图集”。将第一个纹理放在前N行中,然后按顶行的N / 2跟随它。包装第二个纹理的底部N / 2行,然后是第二个纹理,然后是顶部N / 2行。最后,做第一个纹理的底部N / 2行。对于访问第一个纹理的UV,对V参数执行相同的除以4。对于第二个纹理,您需要除以4并添加0.5 这应该可以正常工作,直到MIP地图级别太小以至于两个纹理混合在一起......但我怀疑这确实是一个问题。