Performance and Delivery

What Is the KTX2 Texture Format?

KTX2 is a texture container, not one GPU compression format. It packages texture structure, metadata, mip levels, and a payload that may already be GPU-native or may be Basis Universal data transcoded at runtime into BC, ASTC, ETC, or an uncompressed fallback.

Intro Game developersTechnical artistsWebGL developers Published

Direct answer

KTX2 separates the file on disk from the texture in GPU memory

Treat KTX2 as the delivery container. Choose ETC1S or UASTC as a transmission payload when portability is the goal, then let a compatible runtime select a supported GPU format. Calculate VRAM from that final format, dimensions, and mip chain—not from the .ktx2 file size.

Ownership boundary: This guide explains the container and transcode decision. Texture Compression Calculator and KTX2 Texture Converter Planner own upload analysis and planning; neither tool currently claims to encode a .ktx2 file.

What you will get

  • Explain why KTX2 is a container rather than one compression format.
  • Separate delivered bytes, Basis payload, runtime transcode target, and resident GPU memory.
  • Choose a starting payload and color-space rule, then verify it on the target device.

When a KTX2/Basis workflow is worth evaluating

  • A web or cross-platform runtime needs one Basis Universal delivery asset that can adapt to supported GPU formats.
  • A team is comparing ETC1S and UASTC for color, normal, or packed data textures.
  • A small .ktx2 file appears to use more VRAM than its download size suggests.
  • A renderer shows black textures, color-space errors, block artifacts, or uncompressed fallbacks.

Acceptance test

Approve the asset only when these are true

  • The KTX2 payload is identified as GPU-native, uncompressed, ETC1S/BasisLZ, or UASTC—not described only as “KTX2 compression.”
  • Color textures carry sRGB transfer metadata while normal and scalar data maps remain linear.
  • Every intended runtime initializes its KTX2/Basis loader and detects supported output formats before upload.
  • Resident memory is budgeted from the chosen GPU format, dimensions, block size, and mip levels.
  • ETC1S and UASTC candidates are visually compared on representative target hardware.
  • A fallback path is measured, including the possibility of uncompressed RGBA8 residency.

What does a KTX2 container store?

A KTX2 file begins with an identifier and fixed header, followed by a level index and supporting structures such as the Data Format Descriptor, optional key/value metadata, optional supercompression global data, and one payload for each mip level. Arrays, cubemaps, and 3D textures add layers, faces, or depth to the same container model.

The Data Format Descriptor is critical: it records the data model, channel interpretation, transfer function, primaries, block dimensions, and sample layout needed to move texture data between tools and runtimes without guessing.

What did the PLAYTEX AI KTX-Software 4.4.2 test measure?

On August 29, 2026, PLAYTEX AI encoded the same 512 × 512 sRGB brick albedo PNG with a complete 10-level mip chain using official Khronos toktx v4.4.2. The 304,635-byte source produced a 32,755-byte ETC1S/BasisLZ KTX2 and a 284,789-byte UASTC/Zstandard KTX2.

ktxinfo reported VK_FORMAT_UNDEFINED for both universal payloads. The ETC1S file used KTX_SS_BASIS_LZ and KHR_DF_MODEL_ETC1S; the UASTC file used KTX_SS_ZSTD and KHR_DF_MODEL_UASTC. Both declared KHR_DF_TRANSFER_SRGB and BT.709 primaries. These are reproducible file-size measurements for one source and encoder setup, not a perceptual-quality verdict.

Why file size and VRAM disagree

BasisLZ or Zstandard reduces delivered bytes, but the GPU samples the format produced after transcoding or decode. A 4 × 4 target using 16 bytes per block, such as BC7 or ASTC 4 × 4, has an 8-bits-per-pixel base allocation before mip overhead; another ASTC block size can use fewer bits per pixel.

Streaming may keep only part of the mip chain resident, while small mips still round to complete compression blocks. Profile runtime residency when that distinction matters; the calculator provides deterministic planning math rather than a driver-allocation guarantee.

Plan KTX2 delivery without confusing it with runtime memory

KTX2 is a texture container, not one GPU compression format. It packages texture structure, metadata, mip levels, and a payload that may already be GPU-native or may be Basis Universal data transcoded at runtime into BC, ASTC, ETC, or an uncompressed fallback.

Step 1: Classify every map as color or data

Treat base color or albedo and color emission as sRGB. Keep normal, roughness, metallic, ambient occlusion, height, opacity data, and packed masks linear unless the target pipeline explicitly documents another convention.

Step 2: Optimize dimensions and channels before encoding

Remove duplicates, unused alpha, and unjustified resolution first. Use Texture Memory Calculator for the set-level budget and Game Texture Optimizer for measurable source changes before KTX2 packaging.

Measure the texture set

Step 3: Encode representative ETC1S and UASTC candidates

ETC1S plus BasisLZ often prioritizes smaller delivery. UASTC plus optional Zstandard generally prioritizes fidelity and efficient ASTC/BC7-oriented transcoding. Keep encoder options and version with the asset.

Step 4: Initialize the runtime transcoder and detect support

A compatible loader must inspect available compressed formats before selecting the output. In Three.js r185, KTX2Loader requires detectSupport(renderer) before loading Basis Universal KTX2 textures.

Step 5: Measure the resident target and visual result

Confirm the actual BC, ASTC, ETC, PVRTC, or uncompressed output; calculate its complete mip chain; and review color, normals, thin features, and motion on representative hardware.

A platform table is a starting hypothesis, not a support guarantee

KTX2 delivery and likely runtime targets by platform class; the device and renderer remain authoritative.
TargetDelivery choiceLikely resident targetVerify
Web / Three.js r185Basis Universal in KTX2KTX2Loader.detectSupport(renderer) chooses an available compressed target before load.Three.js KTX2Loader documents Basis Universal support; it does not parse every hardware-specific KTX2 payload.
Desktop GPUETC1S for smaller transfer or UASTC for higher fidelityBC7 is a strong UASTC target where supported; BC1/BC3 remain possible lower-feature fallbacks.Choose by texture role and actual API/device support, not the desktop label alone.
Modern mobile / XRETC1S or UASTC in KTX2ASTC is a common high-quality target on supported hardware; ETC2 can serve as a fallback.Block size changes ASTC memory and artifacts. A runtime target is not implied by the .ktx2 extension.
Limited or unsupported targetSame KTX2 may still be readable by the transcoderThe runtime may choose another block format or decode to uncompressed RGBA8.RGBA8 fallback can erase the expected VRAM savings even when delivery remains compact.

Failure symptoms that reveal the wrong layer is being debugged

  • File is small but VRAM is not: Inspect the resident GPU format, mip count, and dimensions. Do not use delivered .ktx2 bytes as a VRAM number.
  • Texture is black or the loader errors: Initialize the transcoder, detect renderer support before load, and confirm the runtime accepts the actual KTX2 payload.
  • Color looks washed out or too dark: Use sRGB decoding for color textures and linear sampling for normal, roughness, metallic, AO, height, and packed data.
  • Normal map shows block artifacts: Test UASTC and a high-quality target such as ASTC or BC7; validate reconstructed normals on the target renderer.
  • First load stalls: Profile network transfer, decoder initialization, worker limits, mip upload, and cache behavior separately.
  • Some devices fall back to RGBA8: Record the capability matrix and budget the uncompressed fallback instead of assuming ASTC, ETC2, or BC support everywhere.

Is KTX2 a compression format?

No. KTX2 is a texture container. It can store GPU-native compressed data, uncompressed data, or Basis Universal transmission data such as ETC1S or UASTC. The payload and final resident GPU format are separate decisions.

Does KTX2 always reduce VRAM?

No. A KTX2/Basis file can reduce delivery size and enable device-aware transcoding, but resident memory depends on the selected GPU target, texture dimensions, block size, mip levels, and whether the runtime falls back to uncompressed pixels.

Which textures should use sRGB?

Use sRGB transfer for color textures such as base color or albedo and usually color emission. Treat normal, roughness, metallic, ambient occlusion, height, and packed masks as linear data. Alpha is not gamma-decoded as color.

Should I choose ETC1S or UASTC?

Start with ETC1S when delivery size is the stronger constraint and the texture tolerates its artifacts. Start with UASTC when fidelity, normal/data texture quality, or fast ASTC/BC7-oriented transcoding matters more. Encode a representative set and compare on target hardware.

Does the PLAYTEX AI KTX2 planner create a .ktx2 file?

No. The current KTX2 Texture Converter Planner inspects the source set, separates delivery size from GPU transcode memory, and prepares a reviewed plan. Encoding remains a target-runtime packaging step outside the planner.

Primary sources

Official specifications and renderer documentation

PLAYTEX AI guidance is paired with official specifications and platform documentation where the handoff depends on an outside convention.

  1. Khronos KTX 2.0 File Format Specification
  2. Khronos KTX Developer Guide
  3. Khronos KTX-Software repository and tools
  4. Khronos glTF KHR_texture_basisu extension
  5. Three.js r185 KTX2Loader documentation
  6. PLAYTEX AI KTX2 evidence manifest
  7. PLAYTEX AI ETC1S/BasisLZ KTX2 sample
  8. PLAYTEX AI ETC1S ktxinfo output
  9. PLAYTEX AI UASTC/Zstandard KTX2 sample
  10. PLAYTEX AI UASTC ktxinfo output