Beginner's guide

What happens to a texture inside the GPU

A 300 KB PNG can quietly take up 5 MB of graphics memory. This guide shows why, how GPUs shrink textures with block compression, and how to pick a format. Every idea comes with something you can try.

About 10 minutes5 interactive demos
Start reading

Chapter 1

File size is not memory size

PNG and JPEG are made for storing and sending images. Before the GPU can draw a texture, the image is unpacked into raw texels, usually 4 bytes each.

The GPU samples those texels millions of times per frame, so they must be ready to read. Memory use therefore depends only on resolution and pixel format, not on how well the file compressed. Mipmaps, the pre-shrunk copies used for distant surfaces, add about one third.

Try itGraphics memory calculatorChange the resolution and the number of textures to see how much GPU memory the same textures need in each format.
Resolution
  • RGBA8
    32 bits per texel
    213 MiB
    Baseline
    21.3 MiB per texture
  • BC7 · ASTC 4×4
    8 bits per texel
    53.3 MiB
    4× smaller
    5.3 MiB per texture
  • BC1 · ETC2 RGB
    4 bits per texel
    26.7 MiB
    8× smaller
    2.7 MiB per texture
  • ASTC 6×6
    3.56 bits per texel
    23.8 MiB
    9× smaller
    2.4 MiB per texture
  • ASTC 8×8
    2 bits per texel
    13.3 MiB
    16× smaller
    1.3 MiB per texture
  • ASTC 12×12
    0.89 bits per texel
    6 MiB
    35.7× smaller
    612 KiB per texture

Block formats are rounded up to whole blocks at every mip level, so the numbers match what the GPU allocates.

Chapter 2

Why the GPU can't keep PNGs

When a shader samples a texture, it can ask for any texel in any order. The hardware has to find that texel immediately.

PNG and JPEG use variable-length coding: to reach a pixel in the middle, everything before it must be decoded first. GPU formats are fixed-rate instead. Every 4×4 block uses exactly the same number of bytes, so the address of any texel is a simple multiplication. The texture stays compressed in memory, and the texture unit decodes blocks as it reads them.

Try itFind a texelClick any texel of this 32×32 texture. A block format can compute where it is stored; a PNG cannot.

Use the arrow keys to move the selection.

Selected texel
x 13, y 18
Its block
column 3, row 4
Address in BC1
(4 × 8 + 3) × 8 bytes = byte 280

The 64 blocks as they sit in memory

0511

The same texel in a PNG

Decompress rows 0 to 18 first (19 of 32)

Chapter 3

Inside a 4×4 block

BC1, the oldest widely used format, shows the idea most clearly. It stores a block of 16 texels in only 8 bytes.

The encoder chooses two endpoint colours. The decoder blends them into four colours on a straight line, and each texel keeps a 2-bit number pointing to the closest one. Blocks with smooth colour changes survive well; blocks that mix several unrelated colours do not.

Try itBC1 block explorerChoose a 4×4 block in the sample texture and see exactly how BC1 stores it.
Block 12, 4

Chapter 4

Many formats, different trade-offs

Newer formats spend their bits more cleverly than BC1: more endpoints, several colour lines per block, better alpha, or a choice of block sizes.

BC7 and ASTC 4×4 use 8 bits per texel and look close to the original. ASTC trades quality for size through its block size: a block is always 128 bits, so a 12×12 block costs less than one bit per texel. Basis Universal takes a different route. It ships one compact file and transcodes it on the device into a format that GPU supports.

Common GPU texture formats
FormatBits per texelAlphaTypical platformsBest for
BC141-bitDesktop, consolesOpaque colour on a tight memory budget
BC38YesDesktop, consolesColour with smooth alpha in older content
BC44Data channelsDesktop, consolesOne channel: masks, roughness, height
BC58Data channelsDesktop, consolesNormal maps (X and Y)
BC6H8NoDesktop, consolesHDR colour such as skyboxes and lightmaps
BC78YesDesktop, consolesHigh-quality colour, with or without alpha
ETC14NoNearly all AndroidOpaque colour on very old devices
ETC24–8YesAndroid, iOSWidely supported mobile fallback
ASTC0.89–8YesModern Android and iOS, Apple SiliconAdjustable quality on mobile
PVRTC2–4YesOlder iPhone and iPadOlder Apple devices only
Basis ETC1SDepends on the targetYesAny GPU, through KTX2Small downloads that run on any GPU
Basis UASTCDepends on the targetYesAny GPU, through KTX2High quality that runs on any GPU
Try itRun the real encodersCompress the 512×512 sample with the same WebAssembly encoders our tools use, then compare a magnified area.
Runs in your browser. Nothing is uploaded.
Area to magnify
Original
RGBA8
1 MiB in GPU memory
BC1
BC1
4 bits per texel
128 KiB in GPU memory
BC7
BC7
8 bits per texel
256 KiB in GPU memory
ASTC 6×6
ASTC 6×6
3.56 bits per texel
116 KiB in GPU memory
ASTC 12×12
ASTC 12×12
0.89 bits per texel
29 KiB in GPU memory

Press “Run encoders” to compress the sample. The first run downloads the encoders.

Chapter 5

Choosing a format

Two questions narrow the choice quickly: which GPUs must load the texture, and what kind of data does it hold?

Colour textures, normal maps and single-channel masks react differently to compression, and desktop, mobile and web platforms support different format families. Pick your case for a sensible starting point, then check the result on your own textures.

Try itFormat chooserPick where the texture runs and what it contains.
Where will it run?
What is in the texture?

Start with

ASTC 6×6

Also consider: ASTC 4×4 · ETC2 RGB

ASTC works on modern Android and iOS GPUs. 6×6 is a good balance; use 4×4 for key assets and ETC2 for older devices.

Open the ASTC encoder

Chapter 6

Practical tips

A few habits prevent most texture compression problems.

  1. 01

    Mark colour as sRGB and data as linear

    Albedo and UI textures are sRGB. Normal, roughness and other data maps must stay linear, or lighting will be wrong.

  2. 02

    Give normal maps their own format

    Use two-channel formats such as BC5 or EAC RG11 and rebuild Z in the shader. Colour formats waste bits and add visible bumps.

  3. 03

    Generate mipmaps

    They add about 33% memory but stop distant surfaces from shimmering and make sampling faster.

  4. 04

    Keep dimensions block-friendly

    Most formats work in 4×4 blocks, so sizes divisible by 4 avoid padding. Older formats such as PVRTC also need square power-of-two sizes.

  5. 05

    Check real content on real devices

    Compare the decoded result with the original at full zoom, and confirm the format is supported by your target GPUs.

Frequently asked questions

Is GPU texture compression lossless?

No. BC, ETC, ASTC and PVRTC are lossy formats with a fixed size per block. How much quality is lost depends on the format, the block size and the image.

Why not use PNG or JPEG textures directly?

They download faster, but the GPU cannot sample them, so they are decoded to raw texels and use full memory. GPU formats stay small in memory as well.

Which texture format is best?

BC7 is a strong default on desktop, ASTC on modern mobile devices, and KTX2 with Basis Universal when one file must work on many GPUs, as on the web.

What does bits per texel mean?

It is the average storage cost of one texel. Raw RGBA8 uses 32 bits, BC1 uses 4, BC7 uses 8, and ASTC ranges from 8 down to about 0.89 depending on its block size.

Try it on your own textures

Every encoder runs locally in your browser. Upload a PNG or JPEG, choose a format and compare the result.