The curse of texture magnification is blurring. There are not enough texels when the texture is blown up on a small display, so the texturing hardware interpolates new ones that smooth out the color transitions. Sometimes you have the opposite problem. The texture has a lot of texels that you are trying to fit on a very small display. This is the problem of texture minification.
Texture minification has a curse of its own. When there are more texels than fragments to display them, some texels may be squeezed out, and features of the texture will not be rendered.
The effect of undersampling can be seen in this rendering of a checkerboard texture:
At the far center of the checkerboard, you can see what looks like a stretched row of checks. That row is actually several rows. They appear as one row because the complementary rows between them have been skipped over. Rotate the floor and you will find other distracting patterns on the horizon.
When a high frequency pattern is inadvertently reproduced at a lower frequency, you have aliasing. Changing the minification filter to linear doesn't fix aliasing artifacts. There are simply not enough fragments sampling the texture for it to be faithfully reproduced on the horizon of this checkerboard.
A graphics developer named Lance Williams proposed a fix for texture aliasing in 1983. He suggested providing a "pyramid" of different resolutions of a texture. Level 0 of the pyramid is the original texture. Level 1 is a version with half the dimensions. Level 2 is a version with a quarter of the dimensions. And so on. At the top of the pyramid is a 1x1 version of the texture. Generating the pyramid is easier if level 0 has dimensions that are powers of 2. Powers of 2 split in half cleanly.
The checkerboard has these four levels leading to the top of its pyramid:
The images are scaled up so that you can see them. All levels are a clean checkerboard pattern save for the very top 1x1 image, which blends the white and black into gray.
The pyramid of images is called a mipmap. Mip- stands for "multum in parvo", which means "much in little" in Latin. The word "little" refers to the fact that the extra resolutions increase the overall size of the texture by only a third.
You can generate and upload the other levels of a texture yourself, or you can let WebGL do it for you by calling generateMipmap
on the currently bound texture:
gl.generateMipmap(gl.TEXTURE_2D);
When a texel and pixel are about the same size, level 0 is used when you perform a texture lookup. As the texels get smaller than the pixel, the lower-resolution levels are used. Try switching the mipmap filter in the renderer below. Which combination of minification filter and mipmap filter look most pleasing?
Setting the mipmap filter to nearest makes the texture lookup pull from the mipmap level closest to the pixel size. Linear makes the texture lookup blend the colors from two surrounding mipmap levels.
As you climb the pyramid, the texels from the lower level are blended together. The blending is what makes the horizon gray. Mipmapping effectively prefilters the texture so that its details are smoothed out rather than lost altogether.
Adding mipmapping to your renderer requires just two steps. The first step you have already seen: you must upload the mipmap levels. The second step is to use a minification filter that makes the texturing hardware pull colors from the smaller resolutions. With two kinds of interpolation between texels and three mipmap settings, a total of six different minification filters are available:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
The controls in the render above let you examine each of these six possible minification filters.