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:
- Distortion: if proportions on the map do not match those on the surface, the texture looks stretched.
- 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.