How texture packing worked before texture atlases were automatic

Extreme close-up of a circuit board showing memory chips and gold contact fingers

Look closely at PC game art from the late 1990s and patterns emerge: textures at consistent small sizes, palettes shared across unrelated surfaces, repetition that looks deliberate and is often necessity. These are the fingerprints of memory limits that no longer exist.

The constraint

An early consumer 3D accelerator might carry four megabytes of memory, shared between the frame buffer, the depth buffer and textures. After the buffers took their share, what remained for textures was small, sometimes under two megabytes.

Textures had to be resident in that memory to be used. Anything not resident had to be transferred across the bus mid-frame, which was slow enough to be visible as a stall. Managing residency was therefore a central performance concern rather than a detail.

There were hard shape constraints too. Dimensions generally had to be powers of two, and many chips imposed limits on maximum size and on aspect ratio. An artist could not simply produce an image of whatever size suited the surface.

What artists did about it

The responses are visible in the finished art once you know to look for them.

  • Small tiles repeated across large surfaces, rather than large unique textures. A 128×128 tile covering a whole wall costs a fraction of a unique texture.
  • Detail concentrated where the player would be close, with distant geometry given the cheapest possible surfaces.
  • Shared palettes across a level, so that a single palette load served many textures.
  • Geometry designed to hide seams, because tiling seams were unavoidable and the alternative was hiding them with level layout.

The tiling aesthetic that reads as period style today was substantially a memory budget expressed as art direction. It happens to have aged well, which is partly luck and partly that constraints tend to produce consistency.

Atlases, assembled by hand

Combining many small textures into one larger image reduces the overhead of switching between them, and the technique was well understood at the time. What did not exist was reliable automation.

Atlases were frequently laid out by hand, or with in-house tools written for one project and never generalised. That made them expensive to change. Adding one texture to a full atlas could mean relaying out the whole thing and updating every coordinate that referenced it.

The consequence was that atlas layout got frozen early in a project, and later art had to fit whatever space remained. Art produced late in development is sometimes recognisably squeezed into gaps, which is not a judgment on the artist.

Filtering created a further trap. Bilinear filtering samples neighbouring pixels, so a texture adjacent to another in an atlas could bleed colour from its neighbour at the edges. Preventing it meant padding borders, which wasted the space the atlas was meant to save. Getting that balance right was a real craft skill.

Compression arrives

Hardware texture compression changed the calculation substantially, offering a fixed compression ratio with decompression handled in hardware at no cost during rendering. Roughly four times as much texture in the same memory, for a quality loss that varied by content.

It was not free of character. The compression schemes handled smooth gradients and photographic detail well, and struggled with sharp colour transitions and particularly with normal maps, producing blocking artefacts around hard edges. Artists learned which content compressed cleanly and which needed to stay uncompressed, and budgeted accordingly.

Why this matters when looking at old assets

Anyone extracting or examining textures from games of this era should expect to find them in hardware-specific compressed formats, at power-of-two sizes, often atlased with padding, and sometimes with palettes stored separately from the image data.

A texture extracted without its palette is not a corrupted file. It is half a file. Similarly, an atlas extracted without the coordinate data that maps surfaces onto it is a picture of a lot of textures rather than a set of textures.

The information needed to reassemble these things is usually present in the game data somewhere. It is just rarely in the same place as the images, because in the original pipeline nothing needed it to be.