Friday, August 20, 2010

Terrain - Anisotropy

First thing I noticed regarding the visual appearance of my terrain is that parts of it are to blurry. And this makes my terrain look less realistic.

To solve it let's use anisotropic texture filtering.

By default I were using trilinear filtering - because used BasicEffect sets linear interpolation for both texture sampling and mip map selection. The blurry artifact that I mentioned (see picture below) is caused by the way how mip mapping works: let's say we have a square shape (with "square-like" texture coordinates) but it gets rendered with a lot larger width than height (in screen space) because of the camera view angle.

The used mip map (mip maps in case of trilinear filt.) gets selected based on the smaller dimension - in our example the height. Because mip maps are squares (width=height) the larger dimension of our shape - the width - "gets" less texels (from texture) thus they need to be stretched. Hence the blurry look.

One could ask: why don't we choose a mip map based on the larger dimension? In that case we would have flickering and aliasing along the smaller dimension which was one of the reasons to create mip maps (second is to gain performance).

Blurry result
Why would be there a flickering? Let's say the smaller dimension (of our rendered shape) is 32 px (in our example the height) and the larger is 256 px (width). We do select a mip map based on the larger dimension to avoid blurring thus mip map 256x256 is selected. In this case 256 texels are mapped for 32 pixels along height. That is circa every 8th texel. Texels between them are simply ignored/"lost". If you start to move the camera and our shape gets little larger or smaller (its height) then every 7th or 9th texel gets rendered. Every 8th texel together will look most probably quite different from every 7th or 9th texel hence the flickering.

This is how it should be
(sharper)
Anisotropic filtering solves both flickering and blurring by saying: do select a mip map based on larger dimension (in our example 256x256) this way we won't have to "stretch" texels thus we won't have any blurring but in case of the smaller dimension take more texture samples. In our example, take 8 samples from the texture for one pixel along height. This way those every ~8 texels won't be lost thus resulting pixel colors will be correct and thus they won't flicker.

That is, the sampling area in the texture has different width and height (its dimension is not isotropic) because it depends on the width/height ratio of the shape (in screen space) and thus on the camera (position+view angle) as well. Hence the name: anisotropic filtering.

Check out the larger picture to see differences between Trilinear and Anisotropic filtering.

Difference between isotropic and anistotropic filtering
(Click on picture for larger image)

Quite a difference, right? 

Note: 
Anisotropic filtering "just" means that more samples are taken depending on width/height ratio but these samples are still interpolated linearly. That is, trilinear and isotropic filtering are not disjoint. Bilinear and trilinear filtering can be used with anisotropic filtering and without it as well. That is, you can have filtering modes like bilinear with our without AF or trilinear filtering with or without AF.

No comments:

Post a Comment