◩ Graphics & images

Textures and UV mapping: coordinates, mipmaps, anisotropic filtering

How a 2D image is applied to a 3D model: UV coordinates, seams, texel density, mipmaps, and bilinear, trilinear and anisotropic texture filtering.

The wood of a table, the bricks of a wall, the fabric of a jacket: in 3D models these details are rarely built with geometry. They are textures, 2D images "wrapped" onto the surface. The operation seems simple, but it raises interesting problems: how to match a flat image to a curved surface, and how to stop that image flickering or blurring when the object moves away or tilts.

UV coordinates

Each vertex of the mesh is given, besides its 3D position, two coordinates (u, v) that point to a location in the image. By convention they run from 0 to 1 on each axis, regardless of the texture's resolution: (0, 0) is one corner of the image, (1, 1) the opposite one.

During rendering, UV coordinates are interpolated across each triangle, and for every pixel the graphics card reads the corresponding color. A pixel of a texture is called a texel, to distinguish it from a screen pixel.

Values outside the 0–1 range are allowed, and the behaviour depends on the addressing mode:

  • repeat: the texture repeats like a tile, useful for floors and walls;
  • mirror: it repeats alternating mirrored versions;
  • clamp: values beyond the limit use the edge texel.

UV unwrapping

Assigning UV coordinates to a complex object amounts to unrolling its surface onto a plane, as is done with a map of the globe or a dress pattern. A sphere cannot be flattened without distortion or cuts: the same goes for almost every object.

There are two choices to make, and they conflict:

  1. Distortion: if proportions on the map do not match those on the surface, the texture looks stretched.
  2. Seams: to reduce distortion the surface is cut into several parts (UV islands), but along the cuts the texture may show discontinuities.

Common sense suggests hiding seams where they are least visible: under a character's arms, on the back of an object, along natural edges.

Texel density

An important practical concept is texel density: how many texels correspond to a metre of surface. If two nearby objects have very different densities, one looks sharp and the other blurry. Keeping density uniform across a scene is one of the hallmarks of careful work.

The minification problem

When an object is far away, a single screen pixel may cover dozens of texels. If the graphics card read only one, a different texel would be chosen with every small camera movement: the surface would flicker, with moiré and sparkles. It is the same aliasing problem met when shrinking an image.

Mipmaps

The classic solution is mipmaps: alongside the original texture, ever smaller versions are stored, each half the previous one in each dimension, down to 1 × 1 texel. A 1024 × 1024 texture therefore has eleven levels.

During rendering, the GPU estimates how many texels fall within a pixel and chooses the appropriate level. The reduced versions were computed in advance with a good filter, so aliasing disappears. The memory cost is modest: all the levels together take up about a third more than the original.

Texture filtering

Method What it does Effect
Nearest neighbour reads the nearest texel blocky look, useful for pixel art
Bilinear average of the 4 nearest texels in one level soft, but visible jumps between mipmap levels
Trilinear bilinear on two mipmap levels and an average of the two continuous transitions
Anisotropic several samples along the direction of tilt slanted surfaces sharp even in the distance

The typical case where the difference shows is a road seen from a car: with trilinear filtering alone, the asphalt quickly becomes a blurry smear, because the GPU picks the mipmap level based on the most compressed direction. Anisotropic filtering samples several times along that direction and keeps the stripes and detail legible.

Textures that are not colors

A texture is simply a grid of values, and it can hold information other than color:

  • normal maps: each texel stores a direction that alters the normal and simulates bumps and grooves without adding geometry;
  • roughness and metalness, for physical materials;
  • ambient occlusion, to darken crevices and corners;
  • displacement maps, which actually modify the geometry.

One point to remember: color textures are generally in sRGB, while data textures (normals, roughness) must be read as linear values. Mixing up the two settings produces materials that are wrong in subtle ways that are hard to diagnose.

Texture compression

GPUs use specific compressed formats (families such as BCn on computers and ASTC on many mobile devices) that allow any block to be read without decompressing the whole image. They are lossy, fixed-rate formats: they greatly reduce memory use, but a JPEG or PNG must still be decompressed and recompressed into these formats before reaching the graphics card.

In short

  • UV coordinates link each vertex to a point on the texture, with values from 0 to 1.
  • Unwrapping a model means balancing distortion and seams; texel density should be kept uniform.
  • Mipmaps eliminate flickering on distant objects for about a third more memory.
  • Anisotropic filtering keeps slanted surfaces sharp.
  • Data textures are read as linear, color textures as sRGB.
MM
Marco Marzaduri

Marco Marzaduri works in cybersecurity, digital forensics and web development. A computer science graduate, he combines rigorous technical analysis with attention to the people who use technology.

Read also