• No results found

Minification Filters and MIP-Mapping

This section is based on the technical sketchMIP-Mapping with Procedural and Texture-Based Magnification [40] presented at SIGGRAPH 2003.

A very common method to deal with texture minification is to use MIP-mapping [183], a concept which is especially important in hardware texture-mapping. Although in some applications, e.g., volume rendering [179], textures are commonly used without MIP-mapping since they are magnified most of the time, many applications have to deal with both mag-nification and mimag-nification of textures. However, higher-order magmag-nification filters cannot be used directly in conjunction with MIP-mapped textures without incurring artifacts in lower-resolution MIP-map levels.

This section shows how the higher-order magnification filters introduced in the previous section can be combined with MIP-mapping in order to be able to use them for both texture minification and magnification, which enables their use in a wide variety of applications. In order to do this, the filter kernel is adapted to the actual MIP-map level used for a given pixel on a per-pixel basis, which allows using arbitrary convolution filters for filtering MIP-mapped textures.

We achieve this by retrieving per-pixel MIP-map level information from ameta MIP-map, and adapting the filter kernel accordingly. The bottom two images of figure 3.1 illustrate the difference between cubic magnification of a MIP-mapped texture without and with per-pixel correction of the filter kernel, respectively.

An approach similar to our meta MIP-map has also been used in the context of shadow mapping [28], and estimating screen space derivatives of quantities such as texture coordinates interpolated during triangle rasterization [133].

Dependence on input texture resolution

The framework for convolution filtering introduced in the previous section depends on know-ledge of the exact resolution of the input texture, which turns out to be the major obstacle when filtering MIP-mapped textures.

First, the input sample values needed must be made available to the pixel shader. In texturing hardware, fast direct access to input samples is not possible, but the same effect can be achieved by using the input texture together with nearest-neighbor interpolation as reconstruction filter. In this way, unaltered input sample values can be made available to the pixel shader. In order to evaluate the convolution sum, the input texture is mapped to the same pixel multiple times with different offsets of whole texels in order to make all input samples to the convolution sum accessible.

In order to be able to do this, the input texture resolution must be known in order to create offsets of whole texels in the texture coordinate domain. Since the entire texture corresponds to a coordinate domain of [0,1]1, a single texel is of size 1/texture size. For example, in a texture of size 64, a single texel has size 1/64, etc. Naturally, for two-dimensional or three-dimensional textures, the width, height, and depth of a texel in the texture coordinate domain can be different and usually need to be calculated separately.

Second, the size must also be known in order to calculate the correct filter weights (in procedural convolution [4]), or retrieve filter weights from the correct locations of a filter kernel texture (in texture-based convolution). The fundamental operation in this case is a multiplication of the input texture coordinates by the size of the input texture, i.e., a scale factor of 64 for an input texture of size 64.

When MIP-mapping is not used, the input texture resolution can simply be made available to the pixel shader as a constant parameter. In order to avoid unnecessary computations in the pixel shader, the size of an individual texel in the texture coordinate domain and the scale factor for filter weight generation or sampling can be specified instead. Texture coordinates can also be generated entirely in the vertex shader, which reduces the load on the pixel shader.

Combination with MIP-mapping

In the presence of MIP-mapping, the problem of providing the pixel shader with the correct input resolution information becomes non-trivial.

The input grid resolution is changed by the hardware on a per-pixel basis by automatic selection of a suitable MIP-map level, and this process is entirely transparent to the pixel shader. That is, even though the pixel shader explicitly requests a given texture to be sampled, it does not know the actual resolution of the texture image that has been sampled if the texture is MIP-mapped. This leads to the problem that correct matching of input samples and filter weights in order to evaluate the filter convolution sum is impossible without knowing the MIP-map level that is actually used for sampling a given texture. To complicate matters further, this MIP-map level cannot even be queried by the pixel shader.

The next section takes a closer look at the problem that occurs when the filter kernel is scaled with respect to the base level image of a MIP-map, which is the natural choice if

1We assume power-of-two textures with texture coordinates of [0,1] mapping to an entire texture, instead of rectangular textures where [0,1] maps to a single texel. Current rectangular texture implementations do not support MIP-mapping at all and are also not available on all platforms.

this scaling has to be constant. After illustrating the basic problem, we then introduce the concept of ameta MIP-map, which we use in order to solve these issues on a per-pixel basis.

MIP-mapping and higher-order filtering with constant filter kernel size If compensation for the actual MIP-map level used for a given pixel is not done on a per-pixel basis, which we propose in the next section, the filter kernel is usually scaled with respect to the base level. In that case, the higher-order magnification filter gradually degenerates to nearest-neighbor interpolation for lower-resolution MIP-map levels. Figure 3.12 illustrates this for three MIP-map levels of lower resolution than the base level.

If the actual MIP-map level resolution is half the resolution assumed by the filter kernel evaluation, adjacent input samples will effectively be replicated once each (in one dimension;

figure 3.12, top row). This replication is a side effect of the way an array indexing operation is simulated in graphics hardware. Since direct access to a given sample in a texture is not possible, the texture must be sampled using nearest-neighbor interpolation instead. However, if the assumed spacing in the texture coordinate domain between two adjacent samples is not correct, nearest-neighbor interpolation will retrieve the same sample multiple times.

Depending on the resampling location, a cubic filter will only use two or three different in-put samples instead of four and thus not be able to achieve the desired result (figure 3.12, top row). Starting with the next-lower resolution MIP-map level (figure 3.12, second row), resam-pling areas start to appear where the reconstruction result is a piecewise constant function and thus the filter starts to behave in a way that is similar to nearest-neighbor interpola-tion. This reduction of reconstruction quality increases rapidly with each MIP-map level (figure 3.12, bottom row). With each successive decrease in resolution, more and more pixels are effectively filtered using nearest-neighbor interpolation. Visually, the result for a res-olution mismatch of 4:1 (two MIP-map levels away from the base level) is already almost identical to nearest-neighbor interpolation, which can also be seen in the bottom left image of figure 3.1.

That is, a straightforward combination of MIP-mapping and higher-order filtering results in filtering quality considerably worse than linear interpolation for many MIP-map levels, which is clearly not what we would expect from a cubic filter, for instance. In the next section, we show how to remove the resulting artifacts and attain consistent higher-order filtering of all MIP-map levels by automatically adapting the higher-order filter to the actual MIP-map level used for a given pixel.

The meta MIP-map

Scaling the filter kernel and adjusting the texture coordinates for fetching input samples once the actual input texture resolution is known in the pixel shader is trivial on current graphics hardware. However, on current hardware it is not directly possible to determine the MIP-map level used for a given pixel, and thus the actual per-pixel input texture resolution. For interpolation between adjacent MIP-map levels, even two input texture resolutions have to be considered for a single pixel.

So the problem becomes how to determine information about the actual MIP-map level or levels used by the hardware for any given pixel.

An additional instruction for determining MIP-map information in the pixel shader would be extremely useful. However, all the required information can also be retrieved from an

Figure 3.12: The input samples used by the reconstruction filter depend on a proper scaling of the filter kernel with respect to the input texture, which can only be done if the input texture resolution is known. Incorrect scaling leads to replication of input samples with respect to the reconstruction filter. The filter effectively uses fewer and fewer input samples, more and more degenerating to nearest-neighbor interpolation.

additional texture that is MIP-mapped and used identically to the actual image texture.

This is possible since two textures that are of the same size and mapped identically will always use exactly the same MIP-map level for any given pixel.

That is, in order to get access to all the required MIP-map level information in the pixel shader, we use an additional MIP-mapped texture that contains no texture data per se, but information about the MIP-map levels themselves. Therefore, we call this texture a meta MIP-map.

All entries in a given level of a meta MIP-map containidentical values. This guarantees that all pixels using this MIP-map level have access to the corresponding MIP-map meta information.

The meta MIP-map can either contain all the information that we need (MIP-map level, size of a single texel, filter scale, see below) directly, or simply contain lookup values into another texture that in turn contains all the necessary information. The choice depends both on the graphics hardware architecture, and memory overhead considerations (see appendix A).

Meta MIP-map contents

The meta information that we need includes:

• The s and t texture coordinate scaling factors for matching filter size and MIP-map level, specified relative to the base level to stay within a [0,1] range (e.g., 0.25 for a MIP-map level of size 16 and a base level of size 64).

• The s and t texture coordinate offsets to get from one texel to the next in a given MIP-map level (e.g., 1/64 for a MIP-map level of size 64).

• The MIP-map level itself, if interpolation between levels is used (i.e., a GL * MIPMAP LINEAR minification filter has been specified). If MIP-mapped float tex-tures are not available, the level must be scaled in order to fit into a [0,1] range, see below.

The meta MIP-map is then used in the pixel shader for adjusting the interpolated texture coordinates to reflect the per-pixel input texture resolution.

Due to precision requirements in texture coordinate arithmetic, both the computations and the (s, t) scale factors and offsets should use floating point precision. This does not necessarily require the meta MIP-map itself to contain floating point data (see below). Floating point values can be stored in an additional 1D texture used as a look-up table, in which case the meta MIP-map itself then only stores fixed point indexes.

Details relevant in practical implementations of the meta MIP-map concept, especially with respect to memory usage and hardware architecture dependencies, are described in Appendix A.

Filtering a single MIP-map level

The resolution of the base level is set as a constant pixel shader parameter, and simple multi-plication with the (s, t) texture coordinate scaling factors from the meta MIP-map yields the scaling factors for the filter kernel that guarantee correct calculation (procedural convolution) or retrieval (texture-based convolution) of weights.

The input texture offsets are either specified by the pixel shader itself, or also specified from outside via the same pixel shader constant used to store the base level size. Simple multiplication with the (s, t) texture coordinate offsets from the meta MIP-map yields the correct texture coordinate offsets to retrieve all input samples required by the filter convolution sum.

These two components combined yield a correct GL CUBIC MIPMAP NEAREST filter, for ex-ample. Since texture-based higher-order filtering can be used with arbitrary filter kernel widths, other higher-orderGL * MIPMAP NEARESTfilters are also possible.

Filtering two adjacent MIP-map levels

If the MIP-map level itself is also stored in the meta MIP-map, it is possible to create GL * MIPMAP LINEAR minification filters with higher-order reconstruction. We only need to observe that the fractional part of the result of the linear interpolation between two adjacent meta MIP-map levels containing the MIP-map level itself yields the interpolation weight that has actually been used by the hardware to interpolate between these levels. The pixel shader can then blend two MIP-map levels that have been filtered with a higher-order filter using this weight, and thus attain smooth transitions between MIP-map levels.

Note that in order to be able to filter two adjacent MIP-map levels with a custom filter, the input texture itself must be sampled twice and be filtered with aGL NEAREST MIPMAP NEAREST minification filter. In order to get access to two adjacent MIP-map levels, the LOD of both texture fetches must be biased accordingly, e.g., using the TXB pixel shader instruction of ARB fragment programand bias values of 0.5 and−0.5, respectively. The meta MIP-map it-self, however, usesGL NEAREST MIPMAP LINEARminification and thus yields the corresponding inter-level interpolation weight.

For storing the MIP-map level itself in the meta MIP-map, it is easiest to use a floating point texture. In this case, floating point textures must support MIP-mapping, which is currently the case on the ATI Radeon 9700, for example, but not on the NVIDIA GeForce FX. However, a scaled version of the MIP-map level fitting into a [0,1] domain can also be used for obtaining a lower-precision interpolation weight. In this case, the value must be scaled back to the MIP-map level in the pixel shader before taking the fractional part.

Section summary and conclusions

After showing that higher-order texture filtering degenerates to nearest-neighbor interpolation for lower-resolution MIP-map levels yielding worse results than linear interpolation for those levels, a result that one usually would not expect, we have described the concept of a meta MIP-map to solve this problem. In practice, the meta MIP-map concept has proven to be very powerful, and the memory overhead can be much lower than initially expected. However, current pixel shader programming interfaces only partially support enough access to MIP-mapping information. First, it would be very powerful to get access to the MIP-map level used for a given pixel without the need for a meta MIP-map in the first place. Second, full access to the Jacobian matrix is very useful for many applications, in our case reducing the memory overhead of the meta MIP-map concept to a negligible amount. Unfortunately, access to the Jacobian is currently not supported in vendor-independent pixel shader interfaces.