如何对纹理进行下采样

时间:2015-04-12 07:31:48

标签: textures gpu mipmaps downsampling

(我在Apple Metal中这样做,但我认为这个问题也适用于OpenGL和DirectX。非常欢迎来自Metal或OpenGL的代码示例。)

我有一个纹理smallTex,其大小是另一个纹理bigTex的大小的倍数。

例如,smallTex的维度为32x32,而bigTex的维度为128x128

我需要将bigTex的内容缩减为smallTex,以便smallTex中的每个像素都包含bigTex中相应像素的平均值。

首先,我想我可以创建一个片段着色器,从bigTex采样并渲染到smallTex。但是,这样我会丢失很多信息,因为采样从最多四个像素读取并在它们之间进行插值。

我需要的是真正的下采样,其中源中的每个像素对结果具有相同的影响。

我读到这可以使用mipmaps(基本上是原始纹理的下采样副本)来完成。但是我必须在bigTex上启用mipmapping,因为我在bigTex上执行了许多渲染(计算)步骤,这将对性能产生负面影响,这将导致大量工作用于GPU更新mipmap。

我需要的是直接GPU命令来对纹理进行下采样。<​​/ strong>

这可能吗?任何提示?

1 个答案:

答案 0 :(得分:1)

Metal texture2d.sample()方法中的线性过滤可以在内核中进行有限的下采样,但它是线性过滤,当下采样因子大于2时,数据可能开始丢失。您当然可以使用这个方法在重复传递到下采样的因子为2,直到你接近。

另一种方法是MPSImageLanczosScale,它将对图像进行Lanczos重采样。一般来说,这对于摄影图像看起来会更好,但对于矢量艺术和其他具有许多精确边缘的内容来说可能是一个糟糕的选择。在这种情况下,您将看到来自lanczos窗口sinc()内核的响铃。

这种振铃还会给神经网络图像识别滤波器带来问题,因为振铃信号可能被误认为是内容(例如头发)并且导致网络准确性的问题。通常情况下,训练网络的方法是使用它。

MPS还提供MPSImagePyramid来生成mipmap。