iOS/Androidでテクスチャを利用する(多分)最も良い方法
Unityの悩みの種であるテクスチャの管理について、
多分もっとも良い方法を簡単に実現する方法が公開された。
方法は簡単で、アルファマスクを使いテクスチャを表現する。
何が良いかと言うと、PVRTC及びETCといった画像を「綺麗」かつ「高パフォーマンス」で運用できる点。及び、iOSとAndroidの切替の手間がほぼ無い点だ。
PVRTCは以前話した通り「アルファを含めなければ綺麗」だ(正しくは露骨に色が変わっている場所が滲む)。なので、アルファのような「露骨に色が変わる部分」は外部に持ってしまうことで、綺麗に表現する。
また、ETCは「全Androidで使える唯一のフォーマット」かつ「SnapDragon(現在のAndroidで最も使われているGPU)」が唯一サポートしている画像フォーマットだ。ただしアルファが使えないというデメリットがあるので、アルファマスクを使うほかない。
この方法を使うことで、1ピクセル辺り8bitで表現することが出来る。(RGBA32を使えば32bit、RGBA16を使えば16bitも表現に負荷がかかる)
(具体的には、圧縮画像マスク付では256x256の画像に対するメモリ消費は64kbだが、RGBA32だと256kbのメモリを消費する。さらに圧縮画像マスクはマスクを使いまわすことでさらに効率化出来る)
この方法の優秀な点は、一つはアルファマップをAlpha 8ではなく圧縮画像で行っている点。確かに考えればアルファ如きに8bitも使う必要は無いし、ファイルサイズも小さくて済む。
非常に面倒さとパフォーマンスのバランスが取れていると思う。
ちなみに、この方法の応用でRGBA32を4bit少なく表現する方法がある(1024x1024だと約500kbの節約)。方法は単純で、RGBA24と圧縮画像マスクを使うだけ。
これならば、RGBA32と遜色ないカラーリングでグラフィックが表現出来る。
ただし、変換に名前を使ってるのは正直いただけないと思う。インポートが非常に面倒だし、自動的に動いてしまう上に恐ろしく時間がかかる。また、PVRTCはマスクを作る際にαを必ず含めなければならないので、α入とα抜きの両方の画像を用意してリネームと非常に面倒。
あれは手動起動に変更した方が良いかもしれない。
圧縮画像は今後も非常に重要になってくる。
圧縮画像を使えば1ピクセルを打つ負荷がRGBA32やRGBA16と比較し1/4から1/8となる。これは解像度がアホみたいに上がっている現状の環境では、ドローコールなんぞより遥かに考えるべき問題だ。
ちなみにpngやjpegといった圧縮フォーマットは、実際にデータを読んだ際はRGBA32として扱われる。アプリサイズ・ファイルサイズ的には有利だがパフォーマンス・ロード時間的に不利なのでその辺り注意。
ちなみに面倒さを無視出来るならば、GPU毎に最適なテクスチャを出力するのがパフォーマンス的には最も良い方法のように思う(概ね4bitで良い表現が出来る)。例えばAssetBundleをGPU毎に用意したり、端末ごとにダウンロードするapkを設定することで実現出来る。(Unityはこれの為にビルド時にテクスチャを設定できるようにしていると思う)
でも面倒くさいので誰もやってないっていうね