Texture Filtering

[Previous] [Next]

Whenever a 3D primitive is rendered, it's mapped onto a 2D image. If you apply a texture to the primitive, Direct3D will use the process known as texture filtering to obtain a color value for every pixel in a primitive's on-screen 2D image.

When a texture-mapped polygon is rendered, the texture you're using will usually be magnified or minified because it's being mapped onto a smaller or larger primitive image. When you magnify a texture (such as when rendering a primitive that takes up 100 × 100 pixels and has a 16 × 16 texture), the same texel can end up being mapped to multiple pixels. This magnification of the texture often makes the rendered image look blocky. When you minify a texture (such as when rendering a primitive that takes up 10 × 10 pixels and has a 256 × 256 texture), a number of texels will be mapped to a single pixel. This minification can generate an image that looks "sparkly" (especially as the primitive is animated). You can diminish both effects by having Direct3D blend several texel colors to generate a more realistic pixel color.

Direct 3D supplies three settings that change the type of texture filtering: min filtering, mag filtering, and mip filtering. Min filtering tells Direct3D how to handle textures that will be minified. Mag filtering tells Direct3D how to handle textures that will be magnified. Mip filtering tells Direct3D how to use multiple mip levels (if they are present) to improve the image further. These three filtering settings can all be changed independently of each other, allowing for a variety of filtering effects. In a sense, filtering is done in two different ways: within a mip level and between mip levels. Min filtering and mag filtering tell Direct3D how to filter texels within a particular mip level. Mip filtering tells Direct3D how to filter texels between the two mip levels that best match the primitive's rendered size. When deciding what values to use for these filter settings, you'll basically be trading off image quality vs. rendering time. Often you'll want to leave the choice of filtering quality to the user.

You can set the current texture filtering method by calling the IDirect3DDevice7::SetTextureStageState method. Set the first parameter to the stage number (0 to 7) of the texture for which you're selecting a texture filtering method. Set the second parameter to D3DTSS_MAGFILTER, D3DTSS_MINFILTER, or D3DTSS_MIPFILTER to select the method you want to use. Set the third parameter to a member of the D3DTEXTUREMAGFILTER, D3DTEXTUREMINFILTER, or D3DTEXTUREMIPFILTER enumerated types that correspond to the second parameter's value.

Nearest Point Sampling

The fastest, but worst-looking, form of filtering is nearest point sampling, in which Direct3D will directly compute the texel address. This address often won't evaluate to an integer, so Direct3D will copy the color of the texel with the closest integer address. If the texture size is similar to the size of the primitive's on-screen image, using nearest point sampling is a quick way to process textures. However, if the sizes are reasonably different, you'll need to magnify or minify the texture. This will make your image appear blocky or sparkly.

You can use nearest point sampling within a mip level by calling the IDirect3DDevice7::SetTextureStageState method. Set the first parameter to the stage number (0 to 7) of the texture that you want to use for texture filtering. Set the second parameter to D3DTSS_MAGFILTER if you want to set the magnification filter. If you want to set the minification filter, set the second parameter to D3DTSS_MINFILTER. Finally set the third parameter to D3DTFG_POINT for the magnification filter and to D3DTFN_POINT for the minification filter. The following code tells Direct3D to use the nearest point sampling with texture stage 0:

 m_pd3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER,                                    D3DTFN_POINT); m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER,                                    D3DTFG_POINT); 

Linear Texture Filtering

Linear filtering is another option. The first two steps of performing linear filtering are the same as the first two steps of performing nearest point sampling: computing a texel address and then finding the texel with the integer address closest to the computed address. The third step of performing linear filtering is to compute a weighted average of the four texels surrounding the nearest sample point—above, below, to the left, and to the right. This makes a huge improvement in the smoothness of the resulting rendered primitive, especially if the primitive is animated. However, the filtering sometimes has the side effect of making the resulting pixels look somewhat blurry. Still, it's an improvement in quality over point sampling.

To select linear filtering, call the IDirect3DDevice7::SetTextureStageState method. Set the first argument to this method to the stage number (0 to 7) of the texture for which you're choosing a filtering method. Set the second argument to D3DTSS_MAGFILTER if you want to set the magnification filter, or set it to D3DTSS_MINFILTER to set the minification filter. Set the third parameter to D3DTFG_LINEAR for the magnification filter and to D3DTFN_LINEAR for the minification filter.

Linear filtering within a mip level (but not between mip levels) is referred to as bilinear filtering, because filtering is done on the nearest texels in the two dimensions of the texture. Here's the code for setting up bilinear filtering for a primitive:

 m_pd3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER,                                    D3DTFN_LINEAR); m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER,                                    D3DTFG_LINEAR); 

Anisotropic Texture Filtering

Anisotropy is the distortion you see in the texels of a 3D object when its surface isn't parallel with the plane of the screen. The shape of each pixel becomes distorted when a pixel from an anisotropic primitive is mapped into texels. Direct3D measures the anisotropy of a pixel as the elongation of a screen pixel that is inverse-mapped into texture space. Direct3D computes the elongation as the length divided by the width.

Anisotropic filtering samples more texels when a screen pixel is elongated, to reduce the blurriness that standard linear filtering can produce. To enable anisotropic filtering, call the IDirect3DDevice7::SetTextureStageState method. Set the first parameter to the stage number (0 to 7) of the texture for which you're choosing a filtering method. Set the second parameter to D3DTSS_MAGFILTER to use the magnification filter or to D3DTSS_MINFILTER to use the minification filter. Set the third parameter to D3DTFG_ANISOTROPIC for the magnification filter and D3DTFN_ANISOTROPIC for the minification filter.

To use anisotropic texture filtering, you also need to set the maximum degree of anisotropy that you want to correct. To do this, call the IDirect3DDevice7::SetTextureStageState method. Set the first argument to the stage of the texture for which you're setting the anisotropy level. Set the second argument to D3DTSS_MAXANISOTROPY and the third parameter to the degree of anisotropy (any value greater than 1). Here's the code for setting up 4:1 anisotropic filtering:

 m_pd3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER,                                    D3DTFN_ANISOTROPIC); m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER,                                    D3DTFG_ANISOTROPIC); m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAXANISOTROPY, 4); 

You can disable anisotropic filtering by setting D3DTSS_MAXANISOTROPY to 1 or changing to a different filter mode. Before setting the degree of anisotropy, check the D3DPRASTERCAPS_ANISOTROPY flag in the D3DPRIMCAPS structure to determine the acceptable range of values for the degree of anisotropy. The higher the value you set for D3DPRASTERCAPS_ANISOTROPY, the longer the filtering will take (because more texels are used to determine the final pixel color). As usual, you will have to make the trade-off between rendering speed and image quality.

Mipmap Texture Filtering

As discussed earlier in the chapter, mipmap textures can decrease the time required for rendering a 3D scene and improve its image quality. Because the memory impact is minimal, I recommend using mipmaps in your applications. Usually the primitive being rendered has a pixel density that falls between the density of two mip levels of a texture. The D3DTSS_MIPFILTER setting can be used to tell Direct3D how to use these two mip levels to generate each final image pixel. If you set it to D3DTFP_NONE, the highest mip level will always be used. If you set it to D3DTFP_POINT, Direct3D will only use the mip level that is the closest match for the primitive's pixel density. If you set it to D3DTFP_LINEAR, Direct3D will linearly blend the two mip levels that best match the primitive's pixel density. Remember that mip filtering is combined with the min and mag filtering settings. For example, if you choose linear filtering for the min and mag settings, but point for the mip setting, Direct3D will choose the closest mip level, perform bilinear filtering on that mip level, and use the result as the pixel value. If instead you choose linear filtering for all of the min, mag, and mip settings, Direct3D will do bilinear filtering on each of the two closest mip levels, then linearly combine the results from each mip level into a single pixel value. This technique, which ends up combining eight pixels, is known as trilinear filtering because it linearly filters in all three dimensions of the texture: u, v, and mip level.



Inside Direct3D
Inside Direct3D (Dv-Mps Inside)
ISBN: 0735606137
EAN: 2147483647
Year: 1999
Pages: 131

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net