facebook rss twitter

Review: NVIDIA ForceWare 70 and 75 MIP Boundary Shimmering with GeForce 7800 GT and GTX

by Ryszard Sommefeldt on 2 September 2005, 00:00

Quick Link: HEXUS.net/qabqn

Add to My Vault: x

Anisotropic Texture Filtering

To understand why you want to filter textures in the first place, never mind using anisotropic filtering, think about texture mapping at its most basic level. Imagine playing your favourite first person shooter game, running along a level that has a large walkway or hallway, with the floor extending out ahead of you into the distance.

To texture map that floor surface, the game has to tell the hardware which texture it's to apply, along with the surface it's to be applied to which in this case is our floor. Imagine the artist for the game has defined a base repeating 256x256 texture to paint that floor with, which he expects the game engine will do. At this point, to save texel sample read bandwidth, the hardware and engine combine to generate a chain of MIP textures.

MIP textures are repeatedly scaled down (usually by a power of two each time) versions of the base texture. Here's an example of a MIP texture chain that I've generated by hand but in the same way the hardware would, (from one of Far Cry's textures), so you can see what I mean visually. Click it for the full uncompressed version and remember that the MIP texture sizes shown are correct only for the full version.

MIP chain from base texture

Every time you scale down by a power of two to create the lower resolution MIP texture, you save a quarter of the texel read bandwidth needed to sample the texture, assuming you sample all the texels, compared to the previous MIP in the chain.

So you can see why, by creating lower resolution versions of the base texture to apply to the surface further away from the viewer where texture detail doesn't need to be so precise, MIP textures are a performance win. Draw distance dictates that you don't need to use the high res texture every time. If there's not that many pixels painting the scene far away in the distance, don't use the largest texture to do so.

However, when you paint the following MIP in the chain next to the last one drawn, especially if it's a high frequency texture (one with a large amount of visual detail, unlike the MIP chain example above) with detail changes at the texture edge, you can clearly see a line on the screen where MIP transitions occur, as the hardware utilises the MIP chain during rendering.

To remove those lines, you need to filter the texels across the boundary. That concept, where you take samples either side of the boundary (for a bilinear filtered MIP transition), is the basis for almost all texture filtering. In the case of the bilinear filter: for every pixel you want to colour, you sample four texels from the texture you're using to draw in a 2x2 box around the pixel centre. You average the colour values from the four samples and use that to colour the pixel. That average, when used across the MIP boundary, is what helps remove the MIP boundary transition.

Trilinear filtering uses two bilinear samples (8 texel samples) to calculate the colour value, reducing the frequency difference (aliasing) and providing the pixel with an even better representation of the colour it should be.

Anisotropic filtering

If a bilinear filter is isotropic, i.e. square shaped (remember the 2x2 box filter kernel shape), an anisotropic filter has a sample frequency that's low on one axis across the texel footprint and high in the other axis, and isn't square any more. Calculating the angle of the surface to be textured using texture coordinates, angle-adaptive anisotropic filtering intentionally varies the number of texels samples depending on how angled the surface is to the viewer. The more shallow the angle, the greater the degree of anisotropy to increase the chances of getting the colour correct by taking more samples.

Sampling the texels using a non-square filter kernel allows you to sample more relevant texels that actually have an effect on the final colour value of the pixel. Texture mapping inherently produces anisotropy due to mapping 2D textures over a 3D surface. So especially when using MIP chains to relieve texturing bandwidth, forcing the use of lower resolution textures, do you want to use a differently shaped filter to calculate the correct pixel colour.

A simple bilinear or even trilinear filter across the MIP boundary isn't enough. You want to change the filter shape and still average the results using a bilinear, trilinear or brilinear (where you trilinearly sample nearest to the viewer and then bilinearly sample everything else) sample of the resulting colour values.

Going back to the simple textured floor example earlier, aniso helps by sampling further across the mip boundaries, taking samples from more relevant texels. Get the position of the anisotropic filter kernel correct and you'll get a great approximation of the pixel colour from the texels you've sampled.

So why've NVIDIA got it wrong recently?