Texture formats fall into three groups serving different purposes.
Source formats
What you author and archive.
- PNG — lossless, alpha, 8 or 16 bit. The safe default for authored maps.
- TIFF — lossless, layered, high bit depth. Common in film pipelines.
- EXR — high dynamic range, floating point. For HDR environment maps and anything exceeding 0–1.
- PSD — layered authoring, not a delivery format.
Delivery formats
What ships in a build or over a network.
- JPEG — lossy, small, no alpha. Fine for base colour, risky for data maps where compression artefacts become surface errors.
- PNG — lossless, larger. Right for maps where artefacts matter.
- WebP / AVIF — better compression than both, for web delivery.
GPU formats
What actually sits in video memory.
- BC / DXT family on desktop
- ASTC on modern mobile
- ETC2 on older mobile
- KTX2 / Basis — a container that transcodes to whatever the device supports, which is why it matters for web and cross-platform delivery.
The important point: PNG and JPEG are not GPU formats. They are decoded to raw pixels at load and then compressed, or worse, kept uncompressed. Shipping PNGs to a game and expecting them to be small in memory is a common and expensive misunderstanding.
Bit depth
8 bits per channel is fine for base colour. Normal maps and height maps benefit from 16, because banding in a normal map shows as visible steps in the lighting.
Colour space, again
Base colour and emissive are sRGB. Roughness, metallic, normal, AO, height are linear data. The file format does not enforce this; the import settings do.
For generated textures
They arrive as PNG or JPEG — source-ish formats. Converting them to your engine's GPU format at import is where the memory decision is actually made, and accepting the defaults is how projects end up texture-bound.