Unity で DDS を読む
概要
Unity で画像をランタイムに読み込みたいとき,速度を重視するならば DDS 形式が便利.Mac では変換に使えるソフトが少ないが,圧縮率を試行錯誤する必要がなければ crunch-osx が便利.
追記: fnord software がDDSを読み書きできるオープンソースの Photoshop プラグインを公開している.ありがとう fnord software 😊😊😊🙏🙏🙏
経緯
問題
Unity に大量の画像をアセットとして突っ込んだらデータぶっこわれガチャが起こったときの様子です pic.twitter.com/oOFZthRvMK
— ボゴソート (@lunar0) November 28, 2016
Unity に100枚くらいのスカイボックス(=600枚の4K×4K画像)を読み込ませたらデータが壊れた.10枚くらいのときは動いていたのでバグなのだろうが,泣いていてもしょうがないのでワークアラウンドを考える.
方法1: WWW.LoadImageIntoTexture()
Unity - Scripting API: WWW.LoadImageIntoTexture
利点
- 簡単
- JPG, PNGが使える
- テクスチャをあらかじめ DDS に変換しておく手間がない
欠点
- 遅い(小さな画像では気にならない)
方法2: Texture2D.LoadRawTextureData
Unity - Scripting API: Texture2D.LoadRawTextureData
利点
- 読み込みが圧倒的に速い
欠点
- 使い慣れたファイル形式が使えない
- DDSに変換するのが遅い
結果
方法1を試したらテクスチャのロード時間が体感的に長かったので,方法2を使うことにした.面倒なので測定はしていないが,体感的に問題にならなさそうだったらわざわざ DDS に変換する必要はないだろうと思われる.画像を DDS に変換するにはそこそこ時間がかかる.1枚30秒〜1分くらい? 少なくとも Unity が JPEG を読み込むよりも遅い.
DDS を読み込む具体的な方法は Can you load dds textures during runtime? - Unity Answers を参照のこと.
注意点
そのまま Unity に読み込むとテクスチャが上下反転されるので, crunch の -yflip
オプションを使う.たぶん OpenGL が左下原点なのと関係があるのだろう.
$ crunch -dxt1 -fileformat dds -mipmode none -yflip -file inputimage.tga