意外とまとまっていないテクスチャ圧縮の概要です。
いろんな職種の人がちゃんと知ってるべきだけど意外と伝わらなかったりするのでまとめてみます。
テクスチャの圧縮とは
テクスチャはピクセルの集まりで、1ピクセルは1色です。
すなわち1ピクセルには1つの色の情報が格納されています。
1つの色の情報は「RGBAの値がそれぞれどの程度か」で表されます。 例えばRとAが最大値でGとBがゼロだったら赤いピクセルになります。
無圧縮のテクスチャの場合、この色情報をピクセルの個数分持つことになります。
これはたとえば100×100ピクセルのテクスチャであれば10000個の色情報を持つことになるので、サイズが大きくなることは容易に想像できます。
この情報量を少なくするための仕組みが圧縮です。 テクスチャの圧縮形式には様々な種類がありますが、一般的によく使われるものにgifとかjpegといったものがあります。
具体的な圧縮のアルゴリズムは圧縮形式により異なりますが、わかりやすい例があったので紹介します。
例えば、画像には数ピクセル同じ色が並んだ領域がよくみられる。そこでピクセル単位に色情報を並べて表現する代わりに、「n個の赤のピクセル」という形で符号化できる。
Wikipedia より
「赤・赤・赤・赤・赤・緑」という情報よりも「赤×5・緑」という情報を持ったほうがデータ量が少なくなるということですね。
GPUとテクスチャフォーマット
それなら自由に圧縮フォーマットを選んでいいのかというと、そういうわけにはいきません。
前節で書いたように、圧縮というのは決まった法則に基づいて行われます。
ということは、圧縮されたテクスチャを使う側がこの法則を知らなければ使えません。
テクスチャを扱うのはGPUであるため、GPUが解読できるフォーマットでないといけません。
この解読できる圧縮フォーマットが、iOSならばPVRTCやASTC(SoCがA8以降のみ)、AndroidならばETC1やETC2(OpenGL ES3.0以降のみ)というわけです。
もし対応していないフォーマットのテクスチャを使おうとすると、
RGBA32という無圧縮の状態に変換され、メモリ負荷が高くなり圧縮している意味が全くなくなってしまいます。
サイズが2のべき乗でなければならない理由
テクスチャサイズは2のべき乗でないといけないというのは常識的なところですが、
これは単純にDirectXやOpenGLがそのサイズしか扱えないためです。
正確にはモバイルに多いOpenGL ESでは2のべき乗以外のサイズも取り扱えるものの、
内部的には結局2のべき乗で扱うので最初からそのように作ったほうが無駄がないということのようです。
参考
http://logicalbeat.jp/wp-content/uploads/2017/02/GCC17_logicalbeat.pdf