next up previous contents
Next: 6.8.1 Texture Subloading Up: 6. Texture Mapping Previous: 6.7 Anisotropic Texture Filtering

6.8 Paging Textures

As applications simulate higher levels of realism, the amount of texture memory they require can increase dramatically. Texture memory is a limited, expensive resource, so loading high resolution images as textures is not always feasible. Applications are often forced to resample their images at a lower resolution to make them fit in texture memory, with a corresponding loss of realism and image quality. If an application must view the entire textured image at high resolution, there may be no alternative to this approach.

But many applications have texture requirements that can be structured so that only a small area of large texture has to be shown at full resolution. For example when textures are used to produce a realistic flight simulation environment, only the textured terrain close to the viewer has to show fine detail; terrain far from the viewer is textured using low resolution texture levels, since a pixel corresponding to these areas covers many texels at once. For many applications that use large texture maps, the maximum amount of texture memory in use for any given viewpoint is bounded.

Applications can take advantage of this phenomena through texture paging. Rather than loading complete levels of a large image, only the portion of the image closest to the viewer is kept in texture memory. The rest of the image is stored in system memory, or on disk. As the viewer moves, the contents of texture memory are updated to keep the closest portion of the image loaded.

There are two different approaches that could be used to address the problem. The first is to subdivide the texture image into fixed sized tiles and selectively draw the geometry that corresponds to each image tile, one at a time, reloading texture memory for each new tile. This approach is difficult to implement. Tile boundaries are a problem for GL_LINEAR filters since the locations where the geometry crosses tile boundaries need to be resampled properly.

The problem could be addressed by clipping the geometry so that the texture coordinates are kept within the [0.0, 1.0] range and then use texture borders to handle the edges of each image tile. Clipping geometry to match each image tile itself can be a difficult problem, especially if the geometry is changing dynamically. For example, terrain close to the viewer might be replaced with more highly tessellated geometry to increase realism, while geometry far from the viewer is tessellated more coarsely to improve rendering performance. In general, forcing a correspondence between texture and geometry beyond what is established by texture coordinates is something to be avoided, since it adds additional complication and software quality problems to the application.

A more sophisticated solution is to take advantage of texture coordinate wrapping to page textures without having to tile the textured geometry. To make this clear, consider a single level texture. Define a viewing frustum that limits the amount of visible geometry to a small area, small enough that the visible geometry can be easily textured. Now imagine that the entire texture image is stored in system memory. As the viewer moves, the image in texture memory can be updated so that it exactly corresponds to the geometry visible in the viewing frustum:

Given the current view frustum, compute the visible geometry.
Set the texture transform matrix to map the visible texture coordinates into 0 to 1 in s and t.
Use glTexImage2D() to load texture memory with the appropriate texel data, using GL_SKIP_PIXELS and GL_SKIP_ROWS to index to the proper subregion.

This technique would remap the texture coordinates of the visible geometry to match texture memory, then load the matching texture image into texture memory using glTexImage2D().

next up previous contents
Next: 6.8.1 Texture Subloading Up: 6. Texture Mapping Previous: 6.7 Anisotropic Texture Filtering
David Blythe