ユーザ用ツール

サイト用ツール


opengl:texturefileformat

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 構造を追加。
opengl/texturefileformat.txt · 最終更新: 2015/07/04 03:11 by oga