A collection of (graphics) programming reference documents
Texture mips, mipmapping, or mipchain, is a form of level of detail for textures. This is a widely used technique that is partially the responsibility of the developer, and partially handled by the hardware and graphics APIs. When a texture has mips, it consists out of multiple elements, where each element is half the resolution of the previous element.
Since each mip level is half of the resolution of the previous level, you can also see that each texel in a mip is the average of the 2x2 texel area of the previous mip. This means that each texel in a mip effectively is the average of the 2mip_index texels2 region of the highest mip level. For example, mip 0 is the average of the 1x1 region, mip 1 is 2x2, mip 2 is 4x4, etc. By calculating these mip levels, most often done offline during some kind of compilation step, we can pre-compute these averages and store them within the texture.
When viewing a model within the world, it will get rasterised will take up a certain amount of pixels. This effectively means that each pixel encompasses a certain area of the model, and as a result encompasses a certain amount of texels of the texture(s) applied to the model. If the model is really close to the camera, the area of the texture being used by a single pixel will be very small. If the model is very far from the camera, the area of the texture being used by a single pixel is very large. This is called magnification and minification.
Remember how when the pixel shader runs, it will only run once for each pixel after rasterisation. This means that we sample the texture of the model at only a single location. However, if minification occurs, we are actually covering multiple texels. By not sampling all of the encompassing texels, we are effectively losing information. This can often cause flickering, or Moiré patterns artefacts and reduce the visual quality of our game.
We could detect the case where minification occurs and sample the texture multiple times, but this would be a very costly operation, as texture samples in the shader are often one of the most expensive operations you can do. Instead we can detect the amount of minification that would occur through some very clever mathematics in the shader, and calculate the appropriate mip level based on that. This results in a texture sample now representing the average of the representative region, as opposed to just a single value, which results in significantly better visual results.
We have mentioned how we can calculate the mips through some very clever math. This is effectively done by having the pixel shader calculate the derivatives of the texture coordinates that would be used for the texture sample. These derivatives are calculated by the texture coordinates of the current pixel and the neighbouring pixels in a 2x2 region. Since the derivatives of the texture coordinates is the rate of change, a high rate of change would indicate that the texture coordinates are vastly different between neighbouring pixels, indicative of minification. If the texture coordinates have a low rate of change, magnification is occurring.
In practice, the calculations of these derivatives and the calculations of the mip is done by the hardware and is mostly hidden from the shader code, resulting in these operations being quite opaque to the shader/render programmer and just working automatically out of the box.
There is actually a secondary hidden reason for mips related to the performance. Since neighbouring pixels are executing on same components of the hardware (see Graphics threading model), this means that they are also sharing the same caches. If these neighbouring pixels are sampling vastly different regions of the texture, any type of cache optimisations that textures tend to be compressed with no longer hold true, resulting in a potentially high cache miss rate. By using mips, we are effectively guaranteeing that we are sampling more neighbouring texels, resulting in a higher chance of having high cache hit rates, resulting in a performance improvement.
Last modified on Friday 23 June 2023 at 15:19:17