Sometimes, especially in objects located far away, you will see textures flickering, with small camera movements causing them to look strange. As discussed earlier, texture maps should be filtered, so each pixel is assigned a value that interpolates the nearest texels to the desired value. But what happens when we are very far from the object? The answer is that the projection of a texel is much smaller than the size of a pixel, so blending four values is not enough. In this case, a slight movement in the camera will result in a quick move per-pixel on texture space. This causes the textures placed on distant objects to flicker and produce an annoying effect. Let's visualize this with an example, such as a quad located very far away but parallel to the screen. One pixel has texture coordinates (0.5, 0.5), whereas the next, in no particular direction, is mapped to (0.65, 0.5). The difference in coordinates comes from the fact that being so far away, coordinates are far apart in texture space. Then, assuming the map is 256x256, the first pixel is mapped to texel (128, 128) plus interpolation. The second is mapped to texel (166, 0.5). Clearly, there's an ocean between both samples. Any minimal camera movement will make a huge impact in texture space and result in very noticeable flickering. See Figure 18.3 for two examples. Figure 18.3. Left image shows an image rendered with texture filtering, whereas the right image shows the same application running with filtering disabled.The solution for this problem is called mipmapping, which is a filtering technique that will make your textures look good regardless of the distance. Mipmapping computes each texture as a sequence of maps each one half the size than the previous. So, if you begin with a 256x256 texture map, your mipmaps will be 128x128, 64x64, 32x32, 16x16, and so on. These downsampled maps are computed by interpolating texels together, so they provide a smooth detail reduction for faraway polygons. Then, at runtime, the triangle to texture is projected in screen space, and the mipmap whose area matches the triangle's area better is used. This way we can eliminate the flickering (at the cost of extra texture memory usage). Reviewing our previous example, imagine that our quad is assigned to the mipmap that is 8x8 pixels in size. Then, the first pixel, with coordinates (0.5, 0.5), will be mapped to texel (4,4). The second pixel, mapped with (0.65, 0.5) as coordinates, will go to texel (5.2, 4), which is contiguous to the previous texel. Mipmaps can be computed automatically in both OpenGL and DirectX. Under OpenGL, they are created with the call: gluBuild2Dmipmaps This call's syntax is very similar to that of glTexImage2D, the standard call for defining and passing a texture to OpenGL. Then, mipmap selection is an automatic process. Under DirectX, mipmaps are handled via the GenerateMipSubLevels call belonging to the IDirect3Dtexture9 interface. Alternatively, mipmaps can be generated automatically at texture creation if we pass the D3DUSAGE_AUTOGENMIPMAP constant in the usage parameter of the CreateTexture call. |