Reputation: 14465
(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
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