2

(I'm doing this in Apple Metal, but I think the question applies to OpenGL and DirectX too. Code examples from Metal or OpenGL are highly welcome.)

I have one texture smallTex whose size is a multiple of the size of another texture bigTex.

For example, smallTex has dimensions 32x32 and bigTex has 128x128.

I need to downsample the contents of bigTex into smallTex so that every pixel in smallTex contains the average values of the corresponding pixels in bigTex.

First I thought I could create a fragment shader which samples from bigTex and renders to smallTex. However, this way I would lose much information, since the sampling reads from at most four pixels and interpolates between them.

What I need is real downsampling, where every pixel in the source has the same influence on the result.

I read that this could be done using mipmaps (which essentially are downsampled copies of the original texture). But then I would have to enable mipmapping on bigTex, which will have a negative performance impact since I'm doing many rendering (compute) steps on bigTex, which would result in a lot of work for the GPU to update the mipmaps.

What I need is a direct GPU command to downsample the texture.

Is that possible? Any hints?

4

1 回答 1

2

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

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

这种振铃也可能导致神经网络图像识别过滤器出现问题,因为振铃信号可能被误认为是内容(例如头发)并导致网络准确性出现问题。通常,网络经过训练是您应该如何使用它。

MPS 还提供 MPSImagePyramid 用于生成 mipmap。

于 2017-01-14T02:44:26.307 回答