目次
Texture File Format
file format | R | RG | RGB | RGBA | sRGB | mip | cube | volume | array | float | int | S3TC/DXT | 3Dc | BPTC | ATITC | PVRTC | ETC1 | ETC2 | ASTC | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3D | 16 | 32 | 64 | 8 | 16 | 32 | BC1/BC2/BC3 | BC4/BC5 | BC6H/BC7 | v1 | v2 | EAC | 2D | 3D | |||||||||||
DDS (.dds) | Y | Y | Y | Y | Y | Y | Y | Y | Y(d) | Y | Y | - | Y | Y | Y | Y | Y | Y | y(a) | y(b) | - | y(a) | - | Y | - |
KTX (.ktx) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | - |
PVR (.pvr) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | - | Y | Y | Y | Y | Y | - |
PKM (.pkm) | - | y(e) | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | Y | Y | - | - | ||||
ASTC (.astc) | - | - | - | y(f) | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | Y | Y |
- (a) = Qualcomm(ATI) のコンバータが FourCC を使って格納。おそらく独自仕様。元は Direct3DM 向け。Array 不可
- (b) = PVRTC 独自仕様。FourCC で格納。Array 不可
- (d) = DXGI_FORMAT 表現可能なフォーマットのみ Array を格納可能。DX10 拡張ヘッダ必須。
- (e) = ETC1 のみ格納可能。
- (f) = ASTC の 3D BLOCK 圧縮のみ格納可能。
GPU 向け画像形式に求められる機能
- mipmap/cubemap/volume(3D)/array 等、多サーフェース&多次元データの格納
- int/float や 64bpp, 128bpp 等 HDR データの格納
- DXT1 等の圧縮テクスチャの格納
- R, RG, RGB, RGBA 等の、1~4 任意コンポーネントの格納
- sRGB / Linear の区別
DDS
DirectX7 以前の DirectDrawSurface 構造をそのままファイルに書き込んだもの。 Realtime 3D のテクスチャ画像形式としては非常に扱いやすく、対応ツールも多いのでほぼ標準として使われています。 詳細は下記ページよりどうぞ。
ヘッダサイズは 128byte 固定。DX10 情報が含まれる場合は 20byte 増えて 148byte 固定。可変長エリアがなく扱いが容易です。 littleendian 固定です。
下記の特徴を持っています。
- Mipmap/Cubemap/Volume(3D) を格納できる
- DXT1~DXT5, BC1~BC7 等、圧縮テクスチャを格納できる
- half, float 等、HDR 形式を格納できる
- R32, R32G32, 10_10_10_2 や int16,int32 等、複雑で新しいデータ形式も格納できる
- FourCC で容易に新規フォーマット対応ができる
- 古くから用いられており非常に多くのツールが対応している
- ヘッダ長が固定で読み込みが容易 (DX10 拡張ヘッダの導入によりヘッダサイズは必ずしも固定ではなく 2 種類に増えました)
逆に言えばこれらの特徴を満たす画像フォーマットが他に存在しませんでした。 そのため OpenGL を使う場合でも dds に対応しておくと大変便利です。 欠点は下記の通り。
- Direct3D 10 でフォーマットが拡張されたが古いツールやライブラリで読み込むことができない。逆に新しいツールでは DX10 拡張ヘッダがないと読み込めないものもある。
- OpenGL で追加された新しい圧縮テクスチャに対応できない。
- ヘッダ構造がゆるく冗長性を含んでいるため、ツールによってヘッダ情報にゆらぎがある。ツールによっては読み込めないフォーマットあり。
- DXGI_FORMAT で表現できないフォーマットは DX10 拡張ヘッダを使うことができないため、Array にできない
画像データの入れ子構造は下記の通り。cubemap や array があっても、最初の surface は通常の mipmap 付き 2D texture としてアクセスできます。
( ( ( ( width * height ) * volume_depth ) * mip ) * cube_face ) * array ) cube_face: +X -X +Y -Y +Z -Z
KTX
DDS から遅れること?年、 ようやく DDS 相当の標準フォーマットが登場しました。
ヘッダは 64byte + 追加情報エリア(可変長)。 bigendian/littleendian 両対応で、CPU と一致しない場合は変換が必要です。
OpenGL / OpenGL ES を想定した画像ファイル形式です。 後発なので DDS の機能をほぼ全部含んでいます。
特徴は、OpenGL / OpenGL ES の定義されたフォーマットシンボル値をそのまま格納することです。 例えば GL_UNSIGNED_SHORT_5_6_5 や GL_COMPRESSED_RGB_S3TC_DXT1_EXT や GL_COMPRESSED_RGB8_ETC2 など。
今後対応ツールが増えれば、KTX は標準フォーマットとして用いられるようになるかもしれません。
特徴
- DDS 相当の情報を全部格納できる。
- ヘッダに GL の定義値をそのまま格納するので、テクスチャローダーは OpenGL API に渡すだけで良い
- あとから OpenGL に追加された新しいフォーマットにも即対応できる。ツールやローダーの修正なしに用いることができる
- DDS が対応していない ETC2/EAC など新しいフォーマットを即座に格納できる
- 画像毎に byte size が挿入されるためツールが対応しやすい
欠点
- 新しいフォーマットでまだ対応ツールが少ない。知名度も低い。
- ヘッダが可変長なので DDS よりわずかに処理が増える。
- ヘッダのエンディアンが固定でないので判定や変換が必要になるかもしれない。
- 画像の前に 32bit の情報 (データサイズ) が必ず挿入されるため、アライメント整合が取りにくい。
- 上位互換フォーマットはヘッダのシンボル値をそのまま使ってロードできない場合がある。(ETC2 として ETC1 をロードする場合に問題が発生)
- OpenGL 以外のプラットフォームでは扱いづらい。
可変長ヘッダであること、イメージの直前に 4byte の情報が入るため、データのアライメントを合わせるのが苦手です。 例えば GPU の DMA にあわせて 128byte や 64byte アライメントでイメージを展開しなければならない場合、 ヘッダと本体を分けてロードするかメモリコピーが必要になります。 GL API をそのまま使う分にはあまり気にする必要がありません。
データの並びが dds と異なっているのでローダーは要注意です。mip level が最後になります。
( ( size4 + ( ( ( width * height ) * volume_depth + padding4 ) * cube_face ) * array + padding4 ) * mip ) cube_face: +X -X +Y -Y +Z -Z
enum { KTX_HEADER_MAGIC0 = 0x58544bab, KTX_HEADER_MAGIC1 = 0xbb313120, KTX_HEADER_MAGIC2 = 0x0a1a0a0d, KTX_HEADER_ENDIAN = 0x04030201, }; struct T_KTXHEADER { // 64byte UI32 Identifier[3]; UI32 endianness; // 0x04030201 UI32 glType; // 0: compressed UI32 glTypeSize; // 1: compressed UI32 glFormat; // 0: compressed UI32 glInternalFormat; // Compressed Format UI32 glBaseInternalFormat; UI32 pixelWidth; UI32 pixelHeight; // == 0 1D texture UI32 pixelDepth; // == 0 2D texture UI32 numberOfArrayElements; UI32 numberOfFaces; // +X,-X,+Y,-Y,+Z,-Z UI32 numberOfMipmapLevels; // > 1 UI32 bytesOfKeyValueData; // metadata public: bool IsCompressed() const { return glType == 0; } };
PVR
PowerVR 用の画像フォーマットです。 GPU 固有の形式ですが、DDS では PVRTC を格納できないため併用する必要がありました。 また iOS のように PowerVR しか存在していないプラットフォームでは、事実上標準形式として用いることが可能です。
ヘッダサイズは 52byte + 可変長メタデータ。bigendian/littleendian 両対応。
2012年になってファイルフォーマットが変更になりました。 ヘッダの構造に全く互換性がないので要注意です。 例えばフォーマットを識別する magic の位置も違いますし、データの並びも異なっています。
PVR format version 3
- ヘッダサイズ : 52byte + メタデータ可変長
- magic = 先頭 4byte が 'PVR' 0x03
- PVRTC-2 対応
- データ並びが KTX 順
struct T_PVR3HEADER { // 13x4 = 52 unsigned int Version; // 'PVR' 0x03 unsigned int Flags; unsigned int PixelFormat[2]; // ('argb',08080808) or (PVR3_FORMAT_*,00000000) unsigned int ColorSpace; unsigned int ChannelType; // PVR3_CHANNELTYPE_ unsigned int Height; unsigned int Width; unsigned int Depth; // >=1 unsigned int Surfaces; // >=1 texture array unsigned int Faces; // >=1 cubemap unsigned int MipMapCount; // >=1 unsigned int MetaDataSize; };
( ( ( ( ( width * height ) * volume_depth ) * cube_face ) * array ) * mip )
PVR format version 2
- ヘッダサイズ : 52byte 固定長
- magic = 44byte 目から 4byte が 'PVR!'
- PVRTC-2 非対応
- データ並びが DDS 順
( ( ( width * height ) * mip ) * [cube_face or volume_depth] )
struct T_PVR2HEADER { unsigned int hsize; // == 52 == sizeof(T_PVR2HEADER) unsigned int height; unsigned int width; unsigned int miplevel; // mipcount-1 (0=single plane) unsigned int tformat; // 0x10 0x08 0x01 bit0-7=PVR2_FORMAT_, bit8-31= PVR2_FLAG_ unsigned int datasize; // byte size (one surface size) unsigned int bpp; // bpp unsigned int redmask; // RedMask unsigned int greenmask; // GreenMask unsigned int bluemask; // BlueMask unsigned int alphamask; // AlphaMask unsigned int magic; // == 0x21525650 "PVR!" unsigned int depth; // surfaces (volume or cube) };
PKM
Ericsson ETC1/ETC2/EAC エンコードツール etcpack で定義されているファイルフォーマット。 ETC1/ETC2/EAC 形式しか格納できず、用途は非常に限られていますが Android API が ETC1 圧縮とともに標準で対応しています。
ヘッダサイズ 16byte 固定。bigendian のみ。
// 16byte bigendian unsigned int32 magic; // 'PKM ' unsigned short16 version; // '10' or '20' unsigned short16 type; // 下記参照 unsigned short16 width; // unsigned short16 height; // unsigned short16 active_w; // unsigned short16 active_h; //
version 1.0 (header.version == 10) type: 0=ETC1-RGB, 1=ETC1-RGBA, 2=ETC1-RGB-MIP, 3=ETC1-RGBA-MIP version 2.0 (header.version == 20) type: 0=ETC1_RGB, 1=ETC2_RGB, 2=ETC2_RGBA_OLD, 3=ETC2_RGBA, 4=ETC2_RGBA1, 5=ETC2_R, 6=ETC2_RG, 7=ETC2_SIGNED_R, 8=ETC2_SIGNED_RG
ASTC
ARM の ASTC Encoder が出力するフォーマット。 ASTC の Block Size を格納可能で、ASTC 3D Texture に対応しているのは今のところこれだけです。 その代わり単一のサーフェースしか格納できず、mipmap, array 等はありません。 そのため 3D Rendering 用途には向かないフォーマットです。 主にツールの内部で用いる中間フォーマットとして用いられます。
// 16byte little-endian unsigned int Magic; // 0x5ca1ab13 unsigned char block_x; unsigned char block_y; unsigned char block_z; unsigned char xsize[3]; // L M H unsigned char ysize[3]; // L M H unsigned char zsize[3]; // L M H
return xsize[0] | (xsize[1]<<8) | (xsize[2]<<16);
更新
- 2015/07/04 : 表を更新、ASTC format 追加、ktx, pvr の header 構造を追加。