pub enum Sampling {
Linear,
Nearest,
Cubic,
Mipmap,
}Expand description
How a texture is read between its texels.
Not two samplers. The same argument that keeps tile modes in the shader keeps this there: a sampler baked with a filter would mean one sampler per combination and a descriptor set per draw that used a different one. A linear sampler read exactly at a texel’s center returns that texel and nothing else, so nearest sampling is the coordinate snapped to the nearest center before the read, which is one multiply-floor-divide and no bindings at all.
dart:ui offers four qualities. These are its first two; the other two are
mipmapped and bicubic, and neither exists here to select.
Variants§
Linear
Blend the texels around the coordinate. The right default: an image drawn at any size but its own is otherwise a mess of hard edges.
Nearest
The one texel the coordinate falls in.
What pixel art needs, and what a sprite drawn at exactly its own size wants in order to be certain no neighbor bled in.
Cubic
A bicubic reconstruction over the sixteen texels around the coordinate.
What dart:ui calls FilterQuality.high. Sharper than linear under
magnification, because the curve through four texels along an axis has
a slope where a straight line between two has a corner, and it costs
sixteen reads per fragment to say so.
The particular curve is Mitchell-Netravali with B and C both a
third, which is what Skia’s high quality has always meant and so what a
caller porting from Flutter is expecting. It rings slightly – the
weights go a little negative between one and two texels out – and that
overshoot is the sharpening, not an error in it.
Mipmap
A linear read of the mip level that matches how far the image is being minified, blended with the level either side of it.
What dart:ui calls FilterQuality.medium, and the one quality that
answers minification rather than magnification. Drawn at half its size
an image read linearly skips every other texel and aliases; read from
the level built for that size, every texel of the original contributes.
It needs a texture that was allocated with a chain, since a level that was never made cannot be read. On a texture without one every read lands on the image itself and this is linear – which is a picture that is merely worse rather than wrong, and is what a sampler does with a level it does not have.