WebP vs KTX2 textures: when to use which

These two formats are not competitors. They optimise different resources — bytes over the wire versus bytes in video memory — and picking the wrong one means solving a problem you did not have.

Last reviewed July 27, 2026

The distinction that decides everything

A JPEG, PNG or WebP texture is compressed on disk and uncompressed in GPU memory. The browser decodes it to RGBA and uploads it. A 2048 × 2048 map becomes roughly 16 MB of VRAM plus about a third again for mips — whether the file was 4 MB or 200 KB.

A KTX2 texture using Basis Universal supercompression is transcoded at load time into a GPU-native block-compressed format — BC7 or BC1 on desktop, ASTC or ETC on mobile — and stays compressed in video memory. Same 2048 × 2048 map, roughly a quarter of the VRAM.

Google's model-viewer FAQ puts it in one sentence: KTX2 "won't give much file size difference compared to JPEG, but it vastly reduces the amount of GPU RAM used and accelerates upload to the GPU. Large high-res models can easily run out of GPU RAM on mobile devices, and this is the fix."

WebP (`EXT_texture_webp`)KTX2 (`KHR_texture_basisu`)
OptimisesDownload sizeGPU memory + upload speed
Disk size vs JPEGMeaningfully smallerRoughly comparable
GPU memoryFull RGBA — no saving~4× smaller (block compressed)
Decode costFast CPU decodeTranscode, then direct GPU upload
AlphaYesYes
Extension statusRegistered multi-vendor (EXT_)Khronos ratified
Dimension constraintsNoneMultiples of 4; full mip pyramid when mipmapping
Encoding timeSecondsMinutes for high-quality UASTC
USDZ / AR Quick LookNot supportedNot supported

What KTX2 actually is

The `KHR_texture_basisu` extension — ratified by Khronos — requires KTX v2 images with Basis Universal supercompression, declared as image/ktx2. It defines two modes, and the choice between them matters more than the choice between KTX2 and WebP.

  • ETC1S with BasisLZ — small files, lower fidelity. Good for albedo on small or distant objects, and for large catalogues where bytes dominate. Struggles with normal maps and sharp detail.
  • UASTC — higher fidelity, larger intermediate data, usually paired with Zstandard supercompression. This is what you use for normal maps and any surface where artefacts are visible.

Two constraints from the specification catch people out: image dimensions must be multiples of 4, and when a texture uses a sampler with mipmap minification (or no sampler at all) the KTX image should contain a complete mip pyramid. Stick to power-of-two dimensions and generate full mips and neither will trouble you.

What WebP actually is

`EXT_texture_webp` is a registered multi-vendor extension that lets a glTF texture reference a WebP image instead of PNG or JPEG. It is a straight substitution: same decode-to-RGBA behaviour, better compression ratio. Support is broad across three.js, model-viewer and Babylon.js.

Because it is an extension, a viewer that does not understand it cannot read the texture at all. The spec allows a fallback by keeping the original image as the texture's source with the WebP in extensions — useful if you have unknown consumers, and pure overhead if you do not.

How to choose

  1. One product, a few textures, mobile web. WebP. Your bottleneck is the 4G download, not VRAM. Encoding is fast, support is broad, no dimension rules.
  2. Many textures, or 4K maps, or several models on one page. KTX2. This is the GPU-memory regime, and it is where phones actually fail.
  3. A configurator with many variants loaded at once. KTX2, decisively — variant textures accumulate in VRAM.
  4. Normal maps and fine surface detail. KTX2 in UASTC mode, or leave them as WebP/PNG. ETC1S will visibly damage them.
  5. Destined for USDZ / AR Quick Look. Neither. Plan for PNG or baseline JPEG on that arm of the pipeline.

The USDZ asterisk

The USDZ package specification permits PNG, JPEG, EXR and AVIF inside a package — not KTX2, not WebP. In practice AR Quick Look is most reliable with 8-bit truecolour PNG and baseline JPEG. So if you are shipping to both the web and iOS AR, your texture strategy forks, and something has to re-encode on the USDZ side. Know where that happens in your pipeline, because it is a silent quality step. More in glTF to USDZ converter issues.

Measure the right number

If you take one thing away: track gzipped transfer size and decoded texture memory as two separate budgets. Optimising one while ignoring the other is how you end up with a 2 MB GLB that stutters on an iPhone, or a smooth model that takes eleven seconds to arrive. Neither format fixes both, and pretending otherwise is where most texture advice goes wrong. The rest of the size picture is in reducing GLB file size.

Common questions

Is KTX2 smaller than WebP?
Usually not on disk. KTX2 is roughly JPEG-sized as a file; WebP is typically smaller. KTX2's advantage is that it stays compressed in GPU memory, using around a quarter of the VRAM of an equivalent decoded WebP, PNG or JPEG.
Can I use KTX2 textures in a USDZ file?
No. The USDZ package specification permits PNG, JPEG, EXR and AVIF. AR Quick Look is most reliable with 8-bit truecolour PNG and baseline JPEG, so KTX2 and WebP textures must be re-encoded when converting to USDZ.
Should I use ETC1S or UASTC?
ETC1S for base colour on small or distant objects where file size dominates; UASTC for normal maps and any surface where compression artefacts would be visible. UASTC produces larger data and is usually paired with Zstandard supercompression.
Do KTX2 textures need power-of-two dimensions?
The KHR_texture_basisu specification requires dimensions that are multiples of 4, and a complete mip pyramid when the texture is sampled with mipmap minification. Using power-of-two dimensions satisfies both comfortably.
Check your file

Reading about it is slower than measuring it. Drop your .glb, .gltf, or .usdz in and get every blocker on this page checked against the real bytes — packaging, textures, geometry, AR parity — with the fix for each one.

Check your file free at /scorecardNo account needed to run a check.

Related

Sources