ノーマルマップの圧縮フォーマットは 3DC が有名です。
Tangent Space の法線マップの場合 z の符号が不要なので (x,y,z) のうち
x,y のみ保存しておけば z= sqrt( 1- (x*x + y*y) ) で値が求まります。
上記の通りシェーダー側に多少追加コードが必要となるものの、RGB8 24bpp
ではなく LA8/RG8 など 16bpp の画像に保存することができます。
さらに DXT5 (8bpp) の color, alpha を独立した 2チャンネルとみなして
法線圧縮する手法 (DXT5n) があります。その応用で DXT5 の alpha 圧縮の構造を
用いて独立 2チャンネルを格納するのが 3DC です。
同じように 1 チャンネルの 4bpp フォーマットもあります。
・Block Compression (Direct3D 10)
最近 OpenGL の GPU で見かける latc, rgtc も同様の構造を持った 1,2 チャンネル
圧縮フォーマットのようです。
3DC が Direct3D 10 以降 DXGI で BC4, BC5 と呼ばれているのと同様に、
OpenGL で定義された呼び方だと思われます。
ATI DX9 DX10/DXGI OpenGL ES OpenGL ------------------------------------------------------------ 3DC_X 4bpp ATI1 BC4 LATC1 LATC1/RGTC1 3DC_XY 8bpp ATI2 BC5 LATC2 LATC1/RGTC2
DX10/DXGI FourCC OpenGL ----------------------------------------------------------------------------- DXGI_FORMAT_BC4_UNORM "BC4U" GL_COMPRESSED_RED_RGTC1_EXT 0x8dbb DXGI_FORMAT_BC4_SNORM "BC4S" GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8dbc DXGI_FORMAT_BC5_UNORM "ATI2" GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8dbd DXGI_FORMAT_BC5_SNORM "BC5S" GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8dbe
LATC と RGTC の違いはチャンネルへの展開方法だけです。
RGTC は 3DC や BC5 と互換性があります。
その代わり LATC は DXT5n とシェーダーコードを共有できます。
vec4 tex_normal= texture2D( NormalMap, otexcoord ); // RGTC unsigned, 3DC_XY, RG8 tex_normal.xy= tex_normal.xy * 2.0 - 1.0; tex_normal.z= sqrt( 1.0- dot( tex_normal.xy, tex_normal.xy ) ); // LATC unsigned, DXT5n, LA8 tex_normal.xy= tex_normal.yw * 2.0 - 1.0; tex_normal.z= sqrt( 1.0- dot( tex_normal.xy, tex_normal.xy ) );
RADEON (GL4.1) の場合いくつか注意点があります。
glGetIntegerv( GL_COMPRESSED_TEXTURE_FORMATS, lists )
が列挙を返してきません。代わりに Extension String の
glGetStringi( GL_EXTENSIONS, i ) で判定する必要があります。
また GL_ATI_texture_compression_3dc があっても OpenGL ES 2.0 と違い
rgtc の方を使います。
つまり GL_3DC_XY ではなく GL_COMPRESSED_RED_GREEN_RGTC2_EXT 。
// GL_EXT_texture_compression_latc GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 // GL_EXT_texture_compression_rgtc GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
OpenGL ES 2.0 GPU の場合 Adreno (ATI系) が 3DC、Tegra2 が LATC に対応
しています。
利用可能なカラー圧縮、法線圧縮フォーマットをまとめると下記の通りです。
COLOR COLOR-EA COLOR-IA NORMAL NORMAL-S 1ch -------------------------------------------------------------- PowerVR PVRTC -- PVRTC-A -- -- -- Adreno ATC ATC-A ATC-I 3DC_XY -- 3DC_X Tegra DXT1 DXT3 DXT5 LATC2 LATC2-S LATC1 ZMS DXT1 DXT3 DXT5 (DXT5n) -- -- Mali ETC1 -- -- -- -- --
対応していない GPU は非圧縮 LA8 で代用しなければなりません。
圧縮に対応していても RG(3DC) と LA でシェーダーを完全に共有するのは
難しそうです。
関連エントリ
・Android OpenGL ES 2.0 の圧縮テクスチャ