# Mipmap

Mipmap (from Latin *multum in parvo*, *many in little*), is a digital image that is stored along with progressively smaller versions of itself; mipmaps are useful in [computer graphics](graphics.md), especially as a representation of [textures](texture.md) in which they may eliminate [aliasing](aliasing.md) during rendering. But mipmaps also have other uses such as serving as [acceleration structures](acceleration_structure.md) or helping performance (using a smaller image can speed up memory access). Mipmaps are also sometimes called **pyramids** because we can imagine the images of different sizes laid one on another to form such a shape.

A basic form of a mipmap can be explained on the following example. Let's say we have an [RGB](rgb.md) image of size 1024x1024 pixels. To create its mipmap we call the base image level 0 and create progressively smaller versions (different levels) of the image by reducing the size four times (twice along one dimension) at each step. I.e. level 1 will be the base image downscaled to the size 512x512. If we are to use the mipmap for the common purpose of reducing aliasing, the downscaling itself has to be done in a way that doesn't introduce aliasing; this can be done e.g. by downscaling 2x2 areas in the base image into a single pixel by **averaging** the values of those 4 pixels (the averaging is what will prevent aliasing; other downscaling methods may be used depending on the mipmap's purpose, for example for a use as an accelerating structure we may take a maximum or minimum of the 4 pixels). Level 2 will be an image with resolution 256x256 obtained from the 512x512 image, and so on until the last level with size 1x1. In this case we'll have 11 levels which together form our mipmap.

This RGB mipmap can be shown (and represented in memory) as a "[fractal](fractal.md) image":

``` 
     _______________________________
    |               |               |
    |               |               |
    |    level 0    |    level 0    |
    |      red      |     green     |
    |    channel    |    channel    |
    |               |               |
    |               |               |
    |_______________|_______________|
    |               |level 1|level 1|
    |               |  red  | green |
    |    level 0    |channel|channel|
    |      blue     |_______|_______|
    |    channel    |level 1|l2r|l2g|
    |               |  blue |___|___|
    |               |channel|l2b|_|_|
    |_______________|_______|___|_|+|
```

This may be how a texture is represented inside a [graphics card](gpu.md) if we upload it (e.g. with [OpenGL](opengl.md)). When we are rendering e.g. a 3D model with this texture and the model ends up being rendered at the screen in such size that renders the texture smaller than its base resolution, the renderer (e.g. OpenGL) automatically chooses the correct level of the mipmap (according to Nyquist-Shannon sampling theorem) to use so that aliasing won't occur. If we're using a rendering system such as OpenGL, we may not even notice this is happening, but indeed it's what's going on behind the scenes (OpenGL and other systems have specific functions for working with mipmaps manually if you desire).

Do we absolutely need to use mipmaps in rendering? No, some simple (mostly software) renderers don't use them and you can turn mipmaps off even in OpenGL. Some renderers may deal with aliasing in other ways, for example by denser sampling of the texture which will however be slower (in this regard mipmaps can be seen as precomputed, already antialiased version of the image which [trades memory for speed](space_time_tradeoff.md)). 

We can also decide to not deal with aliasing in any way, but the textures will look pretty bad when downscaled on the screen (e.g. in the distance). They are kind of noisy and flickering, you can find examples of this kind of messy rendering online. However, if you're using low resolution textures, **you may not even need mipmaps** because such textures will hardly ever end up downscaled -- this is an advantage of the [KISS](kiss.md) approach.

One shortcoming of the explained type of mipmaps is that they are *isotropic*, i.e. they suppose the rendered texture will be scaled uniformly in all directions, which may not always be the case, especially in 3D rendering. Imagine a floor rendered when the camera is looking forward -- the floor texture may end up being downscaled in the vertical direction but upscaled in the horizontal direction. If in this case we use our mipmap, we will prevent aliasing, but the texture will be rendered in lower resolution horizontally. This is because the renderer has chosen a lower resolution of the texture due to downscale (possible aliasing) in vertical direction, but horizontal direction will display the texture upscaled. This may look a bit weird, but its completely workable, it can be seen in most older 3D games.

The above issue is addressed mainly by two methods.

The first is [trilinear filtering](trilinear_filtering.md) which uses several levels of the mipmap at once and [linearly blends](linear_interpolation.md) between them. This is alright but still shows some [artifacts](artifact.md) such as visible changes in blurriness.

The second method is [anisotropic filtering](anisotropic.md) which uses different, *anisotropic* mipmaps. Such mipmaps store more version of the image, resized in many different ways. This method is nowadays used in quality graphics.