Jonas Sourlier
Jonas Sourlier

Reputation: 14465

How to downsample a texture

(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?

Upvotes: 3

Views: 2291

Answers (1)

Ian Ollmann
Ian Ollmann

Reputation: 1592

The linear filtering in the Metal texture2d.sample() method can do limited downsampling right in your kernel, but it is linear filtering and data can start to get lost when the downsampling factor is more than 2. You can of course use this method in repeated passes to down sample by factors of two until you get close.

Another method is MPSImageLanczosScale, which will do a Lanczos resampling of the image. Generally this will look much better for photographic images, but can be a poor choice for vector art and other content with lots of precise edges. In such cases, you will see ringing from the lanczos windowed sinc() kernel.

This ringing can also cause problems for neural networking image recognition filters, since the ringing signal can be mistaken for content (e.g. hair) and cause problems for the accuracy of the network. Typically, however the network is trained is how you should use it.

MPS also provides MPSImagePyramid for generating mipmaps.

Upvotes: 2

Related Questions