Skip to content
Techniques & Technology

Texture Mapping

Images on polygons

Texture mapping wraps 2D images onto 3D surfaces, adding visual detail to polygonal models without the geometric complexity that would otherwise be required.

ibm-pcsony-playstationsega-saturnnintendo-643dgraphicsrendering1992–present

Overview

Polygons alone look flat and lifeless. Texture mapping wraps 2D images — textures — onto 3D surfaces, giving them detail that geometry couldn’t practically provide. A brick wall doesn’t need thousands of polygons; it needs one rectangle with a brick image. The technique became fundamental to real-time 3D graphics from Doom (1993) onward and remains the foundation of modern GPU pipelines.

Fast facts

  • Purpose: Add surface detail without geometric complexity.
  • Method: UV coordinate mapping — each vertex carries a (U, V) coordinate into a texture image.
  • Benefit: A 1000-pixel-wide brick texture costs the same vertices as a 1-pixel-wide flat colour.
  • Hardware: Modern GPUs have dedicated texture units; 1990s consoles had wildly varying capabilities.

UV coordinates

Each vertex of a polygon carries a 2D coordinate (U, V) that points into the texture image. The renderer interpolates these UVs across the polygon’s interior, sampling the texture at each pixel:

Concept Function
U axis Horizontal texture position (0.0 = left edge, 1.0 = right edge)
V axis Vertical texture position (0.0 = top, 1.0 = bottom) — convention varies by API
Mapping Texture-coordinate-to-vertex association set by the artist
Interpolation Renderer fills polygon interior, computing UV at each pixel
Sampling Look up the texture pixel at the interpolated UV

Mapping methods

How artists assign UVs:

Type Application
Planar Flat surfaces — project from one axis (floors, walls, billboards)
Cylindrical Rounded objects — wrap the texture around an axis
Spherical Globes, balls, eyeballs
Cube map Six textures, one per cube face — used for skyboxes
UV unwrap Complex shapes — manually flatten the model into a 2D layout

Modern 3D modelling software (Blender, Maya, 3ds Max) provides interactive UV unwrapping tools that flatten meshes into 2D atlases.

Perspective correction

The hardest part of 1990s real-time texture mapping. The naive approach (linearly interpolate U and V across screen space) is affine texture mapping; it produces visible warping when polygons are at sharp angles to the camera. The correct approach is perspective-correct — interpolate U/Z and V/Z linearly, then divide by 1/Z per pixel.

Issue Solution
Affine distortion Visible warp on tilted polygons (PSX is the famous example)
Per-pixel division Compute U/Z, V/Z, and 1/Z; divide at every pixel; perspective-correct
Hardware support GPU divides per pixel for free; software renderers ration this expensive operation
Software fallback Subdivide polygons into smaller pieces so affine looks better; slow

The per-pixel division was prohibitively expensive on 1990s consoles without dedicated hardware. Doom uses affine mapping for walls (always vertical, mostly camera-facing), and avoids tilted floors. Quake (1996) introduced subdivision-based perspective correction in software, then later versions used 3dfx Voodoo’s hardware perspective correction.

Platform approaches

The 1990s console wars produced three distinct compromises on texture mapping:

Platform Method Visible artefacts
PlayStation 1 Affine, no perspective correction; integer-only UV units Heavy warping on tilted polygons; texture “swimming” as polygons move
Sega Saturn Quadrilateral rasterisation with forward differencing Different artefacts — texture distortion at quad edges; less visible warp
Nintendo 64 Perspective-correct, with bilinear filtering and 4 KB texture cache Smaller texture sizes (most N64 games use 32×32 or 64×64 textures); blur from filtering
3dfx Voodoo (PC) Full perspective-correct, mipmapped, bilinear/trilinear The gold standard of mid-90s texture mapping
PowerVR (PC, Dreamcast) Tile-based deferred rendering with perspective correction Different rendering architecture; very efficient at the time

The PlayStation’s affine mapping became its visual signature — every PSX game has the characteristic floor-warping look. Subsequent re-releases sometimes patch this; modern emulators (Duckstation) offer perspective-correct interpolation as an optional enhancement.

Filtering methods

How to sample a texture when the screen pixel doesn’t align with a texture pixel exactly:

Filter Quality Cost
Nearest neighbour Pixelated; preserves the original art One sample per pixel
Bilinear Smooth, slightly blurry Four samples + linear blend
Trilinear Smooth across mipmap levels Eight samples (two mipmap levels × four each)
Anisotropic Sharp at oblique angles Variable — up to 16 samples per pixel

The choice between nearest-neighbour and bilinear is partly aesthetic. Modern pixel-art-style 3D games often use nearest-neighbour deliberately to preserve crisp pixel boundaries; AAA games use trilinear or anisotropic for smoothness.

Mipmapping

A texture rendered at distance — covering only a few pixels of the screen — should be sampled from a smaller version of itself, both for performance and to avoid aliasing. Mipmaps are pre-computed half-size, quarter-size, eighth-size… copies of the texture, all stored together:

Purpose Implementation
Distance scaling Pre-scaled versions of the texture (each level half-resolution of the previous)
Performance Smaller textures fit in cache; faster to sample
Aliasing reduction Reduces the “shimmer” caused by sub-sampling high-frequency textures
Memory cost Mipmap chain adds 1/3 to texture storage

Standard chain: a 256×256 texture has mipmaps at 128×128, 64×64, 32×32, 16×16, 8×8, 4×4, 2×2, 1×1.

Memory considerations

Texture memory was the dominant constraint of 1990s 3D:

Factor Impact
Resolution Doubling resolution = 4× VRAM
Colour depth 32-bit RGBA vs 8-bit indexed = 4× memory
Compression DXT / S3TC / BC formats: 4-8× saving
Palettes Indexed colour with shared palettes was the PSX / N64 / Saturn norm
Texture atlas Pack many small textures into one big one to reduce binding overhead

The N64’s tiny 4 KB texture cache forced its games into 32×32 or 64×64 textures — visibly blurry compared to PSX’s larger texture allowance. The PSX’s 1 MB VRAM limit meant aggressive palette use; full-colour textures were rare.

Modern texture features

Beyond simple colour mapping, modern texture pipelines support:

Feature Purpose
Normal maps Per-pixel surface direction → fake high-detail lighting on low-poly models
Specular maps Per-pixel shininess
Roughness maps Per-pixel surface roughness for PBR
Albedo / colour maps The “main” colour texture
Ambient occlusion maps Pre-baked subtle shadowing
Displacement / parallax Per-pixel surface displacement
Cube maps Skyboxes, reflections
3D textures Volumetric data, fog, smoke

Modern PBR (physically-based rendering) pipelines bind 4-8 textures per material. Compare to Quake (1996) using 1 texture per surface plus 1 lightmap.

See also