PDA

View Full Version : Aniso Filtering Theory -- Clarification


15dice
12-23-2006, 01:08 PM
I asked this at another site, but since the DM wiki is the source of my confusion, I figured I'd ask here. :)


My favorite explanation of AF is here (http://www.devmaster.net/wiki/Anisotropic_filtering) on Devmaster:


How mipmapping works
When we render a square, say 256x256 pixels, and we use a square texture of the same size, it will look splendid. But if we tilt that square backward, it becomes more like a rectangle, being more wide than heigh. Let's say its dimensions are 256x32, roughly. This means that the texture that we map onto it is compressed 8 times in the vertical direction. In other words, we would skip 7 out of every 8 lines. All that information is lost. It also causes flickering, aliasing, because when you shift the tilted square up and down, other horizontal lines will become visible and others dissapear. To avoid the flickering, mipmapping uses a 32x32 version of the texture, where blocks of 8x8 pixels of the original texture are nicely averaged together. This is also a loss of information, but it stops the flicker. This is what is done with regular mip-mapping. The biggest disadvantage is that we now have 32 pixels horizontally in the texture, mapped onto 256 pixels on the screen. So we're stretching it out, making it look blurry.

How anisotropic filtering works
What we really wanted is to average 1x8 pixels together, so we'd get a 256x32 texture. But that doesn't work when we start rotating the square. And it also requires a lot of extra memory. The alternative, is to sample the texture 8 times per pixel, in the direction in which the polygon is tilted. That's anisotropic filtering. It doesn't matter how the square is rotated, it can take 8 samples in the texture in any direction required, and average them together. It's called anisotropic because the degree of filtering in one direction (the direction in which the polygon is tilted) is greater than the degree of filtering in the direction perpendicular to that.


My confusion is the italicized/bolded part of the quote above.

(1) Are those eight samples weighted averages?

(2) Are those resulting values then weighted-averaged (i.e. bilinearly filtered) to produce the final color?

Reedbeta
12-23-2006, 01:22 PM
The 8 samples will be taken from one of the mipmaps, which will be selected based on the polygon's screen orientation and size. Like any time a texture image is sampled, bilinear filtering will be applied in case a sample location doesn't fall exactly at the center of a texel. Trilinear filtering involving two adjacent mipmap levels is also possible to avoid visible seams at the transition from one level to another. Then the color results of the 8 samples are averaged together (probably a straight average, not a weighted one) to create the final result of the texture sample.

Nick
12-23-2006, 01:48 PM
Are those eight samples weighted averages?
In the OpenGL specification of the anisotropic filtering extension (http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_filter_anisotropic.txt), N samples are summed and divided by N. So that's the same as giving them equal weights 1/N.

More advanced implementations that better approximate the pixel's footprint on the texture could take the samples at different LOD and different weights. But I don't know of any hardware doing this.
Are those resulting values then weighted-averaged (i.e. bilinearly filtered) to produce the final color?
It actually takes N bilinear or trilinear samples and averages those together. So with trilinear filtering and 8-way anisotropic, 32 texel values are read for one sample. :happy:

Modern hardware can take one bilinear sample in one clock cycle (throughput, not latency). Trilinear takes two clock cycles (two bilinear samples). So 8-way anisotropic with trilinear samples takes 16 clock cycles.

15dice
12-23-2006, 02:10 PM
Thank you both!

It actually takes N bilinear or trilinear samples and averages those together. So with trilinear filtering and 8-way anisotropic, 32 texel values are read for one sample. :happy:


Let me make sure I get this straight:

So, consider we want 8 samples in the vertical direction to be averaged. For each of the 8, we take two horizontal samples and weighted-average them. Then we do the same for a higher mipmap level, and weighted average them. Then we weighted-average the results, based on mipmap distances (giving us trilinear filtering).

We do the above process 7 more times. We then combine the vertical results using a 1/N (1/8 in this case) equal-weighted average?

(In other words, we filter first, then do the unweighted average?)

Reedbeta
12-23-2006, 02:44 PM
Almost right.

For each of the 8, we take two horizontal samples and weighted-average them. Then we do the same for a higher mipmap level, and weighted average them. Then we weighted-average the results, based on mipmap distances (giving us trilinear filtering).

For each sample, we actually do a full bilinear filter, which involves four samples from the mipmap level, not just two horizontal samples as you've described. With trilinear filtering, that's 8 texels (4 each at two different mip levels) involved.

So with trilinear filtering and 8-way anisotropic, 32 texel values are read for one sample.

Nick, isn't it 64 texel values? 8 texels are involved for each trilinear sample, and there are 8 trilinear samples in the anisotropic sample...

15dice
12-23-2006, 04:01 PM
Almost right.



For each sample, we actually do a full bilinear filter, which involves four samples from the mipmap level, not just two horizontal samples as you've described. With trilinear filtering, that's 8 texels (4 each at two different mip levels) involved.



Nick, isn't it 64 texel values? 8 texels are involved for each trilinear sample, and there are 8 trilinear samples in the anisotropic sample...

This is exactly what I was just contemplating, yeah. I was trying to make my explanation fit to the mentioned "32", but bilinear should need 4 texel values. Maybe you can reuse adjacent texel values? I wouldn't know.

15dice
12-23-2006, 05:12 PM
Another question:

If bilinear (not trilinear) filtering were used with AF, then would the smaller or larger mip level be chosen for filtering? I think that the smaller level is traditionally used (since blurry-ness is preferred over flickering).

Nick
12-24-2006, 06:38 AM
Sorry for the confusion. It's indeed 64 texels. I wrote trilinear but computed it for bilinear samples. :blush:
If bilinear (not trilinear) filtering were used with AF, then would the smaller or larger mip level be chosen for filtering? I think that the smaller level is traditionally used (since blurry-ness is preferred over flickering).
OpenGL specifies nearest LOD level (http://oss.sgi.com/projects/ogl-sample/registry/SGIS/texture_lod.txt). Flickering really only happens with high-frequency textures, and blur can be unpleasant too so a compromise works well.

NVIDIA has an interesting optimization for anisotropic filtering that offers a quality between bilinear and trilinear samples. Some call it 'brilinear'. I believe it takes some of the (bilinear) samples on the lower LOD level and some on the higher LOD level. So it has roughly the cost of anisotropic filtering with bilinear samples but also gives a smooth transition like trilinear.

15dice
12-25-2006, 10:26 AM
VERY informative, thanks Nick + others, that answered everything and thensome. ;)