Supported formats

The five Hap variants this package decodes, and the two it detects but rejects.

on this page

Hap is a family of variants rather than a single codec. Each stores frames in a block-compressed texture format the GPU reads directly.

VariantCompressionAlpha
HapDXT1
Hap AlphaDXT5yes
Hap QYCoCg DXT5
Hap Q AlphaYCoCg DXT5 + RGTC1yes
Hap RBC7

Hap Q Alpha decodes as real transparency rather than an approximation: the player uploads two textures per frame — a YCoCg colour plane and an RGTC1 alpha plane — and combines them in a decode shader.

Variants that will not decode

HapA (alpha-only) and Hap HDR (BC6H) are recognised in the container but not decoded. Opening one fails at OpenAsync/Open with HapOpenStatus.UnsupportedFormat rather than producing a broken frame — see open results for the full status list.

Chunked frames

Hap frames may be split into chunks so that decompression can be parallelised. The number of threads used to decompress one frame’s chunks is a process-wide setting, HapPlayer.DecodeThreadCount; see process-wide tuning.

Encoding source material

This package only reads Hap; it does not encode. Encode with whatever tool your pipeline already uses — the variant choice is the meaningful decision:

  • Hap is the cheapest per frame and the largest visual compromise.
  • Hap Q is the usual default when quality matters; it roughly doubles the per-frame byte size of Hap, which is also the thing that dominates playback cost.
  • Hap R (BC7) is the highest quality of the three opaque variants.
  • Reach for the Alpha variants only when you actually need transparency — Hap Q Alpha costs two texture uploads per frame instead of one.

Per-frame byte size is what drives main-thread cost, so it is worth treating the variant and the resolution as one combined budget decision. See playing many videos at once.