为OpenGL纹理使用自己的mipmap创建算法是否有意义?

时间:2009-05-06 21:34:45

标签: opengl textures mipmaps

我想知道如果我使用自己的算法预生成它们而不是内置的自动算法,纹理mipmap的质量是否会更好。我可能会使用一个缓慢而漂亮的算法,比如Lanczos重采样。

有意义吗?我会在现代显卡上获得任何质量增益吗?

4 个答案:

答案 0 :(得分:11)

有充分的理由生成自己的mipmap。然而,下采样的质量不是其中之一。

过去,游戏和图形程序员已经尝试过各种下采样算法。最后,事实证明,非常简单的“平均四像素”方法可以得到最好的结果。此外,更先进的方法在理论上更正确,它们往往会从mipmap中获得很多锐度。这样看起来很平坦(试试吧!)。

对于一些(对我来说不可理解)的原因,简单的平均方法似乎在抗锯齿和保持mipmaps之间的最佳权衡。

但是,您可能希望使用伽马校正来计算mipmap。 OpenGL不会自己做这件事。这可以产生真正的视觉差异,尤其是对于较暗的纹理。

这样做很简单。而不是像这样平均四个值:

float average (float a, float b, float c, float d)
{
  return (a+b+c+d)/4
}

这样做:

float GammaCorrectedAverage (float a, float b, float c, float d)
{
  // assume a gamma of 2.0 In this case we can just square
  // the components. 
  return sqrt ((a*a+b*b+c*c+d*d)/4)
}

此代码假定您的颜色分量标准化为0到1。

答案 1 :(得分:2)

是什么促使你尝试?您目前生成的mipmap是否生成不佳? (也许你看过了吗?)请记住,无论如何你的结果通常仍然是(三)线性插值,所以在一个动作之间通常会有很大的收益来改进重采样。

答案 2 :(得分:2)

这取决于您显示的资产类型。 Lanczos滤波器更接近理想的低通滤波器,如果您并排比较mip贴图,结果会很明显。大多数人会误认为混淆锐度 - 再次取决于你的资产是否包含高频 - 我肯定会看到箱式滤波器不是一个好选择的情况。但是,由于mip映射然后被线性插值,所以增益可能不那么显着。还有一件事需要提及 - 大多数人使用盒式滤镜并将输出作为输入传递到下一个阶段 - 这样你就失去了精确度和视觉能量(虽然伽玛会帮助这个)。如果你能想出使用任意过滤器的代码(请注意,大多数代码可以分成两个过程),你通常会缩放过滤器内核并从基础纹理生成mip贴图级别,这是一件好事。

答案 3 :(得分:1)

作为这个问题的补充,我发现一些完全不同的mipmapping(而不是那些只是试图达到最佳缩小质量的那些,如Lanczos过滤)算法对某些纹理有很好的效果。

例如,在一些应该代表高频信息的纹理上,我尝试过使用一种算法,该算法只需要考虑每次迭代时考虑的四个中的一个随机像素。结果很大程度上取决于质地和它应该传达的东西,但我发现它对一些人产生了很大的影响;尤其是地面纹理。

我尝试的另一个是采用最偏离的四个像素来保持对比度。它的用途更少,但确实存在。

因此,我已经实现了为每个纹理选择mipmapping算法的选项。

编辑:我想我可能会提供一些实践差异的例子。这是地面上的一块草纹,最左边的图片是标准的平均mipmapping,最右边是随机的mipmapping:

Average mipmapping, trilinear filtering Random mipmapping, trilinear filtering

我希望观众能够了解平均mipmap中丢失了多少“明显细节”,以及它对这种纹理看起来多么平坦。

另外作为参考,这里是打开4×各向异性过滤的相同样品(上面是三线性的):

Average mipmapping, 4× anisotropic filtering Random mipmapping, 4× anisotropic filtering

各向异性过滤使得差异不那么明显,但它仍然存在。