こちらでは、思い出せないくらい大変にお久しぶりです。コミPo! でもお世話になっております、開発の小野知之です。久しぶりのブログ記事は、Unityでのテクスチャ画像取り込みについてのお話しです。
はじめに
Unityで、マルチプラットフォーム向けのゲームなどを作成するケースが増えています。弊社の2Dアニメーション作成ツール「SpriteStudio」とUnityを連携してご利用いただいているお客様も増えてきたのですが、それと同時にこんなお問い合わせも増えました。
「作成したテクスチャ画像を、Unityに16bitカラーに変換して取り込むと、画質が大きく落ちてしまう。これは、なんとかならないものか?」
Photoshopなどで作成したテクスチャ画像をUnityに取り込んで使う場合に、「PVRTCでは圧縮ノイズが気になる」「32bitカラーではデータサイズが大きすぎる」といった理由で、「16bitカラー」形式を選択することが多いと思います。しかし、16bitカラーに変換すると、画質が大きく落ちてしまうのです。
そこで当社では、Unityのテクスチャ取り込み処理について調査し、16bitカラー画像への変換時に画質が大きく落ちる原因とその対策方法を見つけましたので、ご紹介します。
※ 本記事は公開時点(2012年7月9日)の情報を元に作成しています。今後のUnityのアップデートなどでご紹介した方法が使用できなくなる可能性もありますのであらかじめご了承ください。
まずは、基本的な「画像の仕組み」についてのおさらいから順に見ていきましょう。すでに良くご存じの方は、前半は軽く読み飛ばしていただいても構いません。
※ なお、本稿の説明では、アルファチャンネル付きの32bitカラー画像を取り込んだ場合を例にして解説しています。アルファチャンネルの無い24bitカラー画像を取り込む場合でも、原因と対策方法は同じです。
通常のフルカラー画像の中身は?
画像の各ピクセルの「色」は、R,G,B,Aの4つの色情報で表現されています。
通常、アルファチャンネルの付いたフルカラー画像(ダイレクトカラー画像とも言います)は、RGBA値をそれぞれ8bit(256階調)として扱っています。このため、画像上の1ピクセルを表現するためには、32bit(RGBA各8bit)の情報量を必要としています。
例えば128×128ピクセルのテクスチャ画像を表示するには、 128×128×32bit=524288bit=64KB の情報量になります。
Unityの16bitカラー画像の中身は?
Unityにテクスチャ画像を取り込むとき、取り込みオプションで「RGBA 16bit」を選択すると、16bitカラー画像に自動変換されます。このUnityの16bitカラー画像では、RGBA値をそれぞれ4bit(16階調)で扱います。このため、画像上の1ピクセルの表示は16bitの情報量になります。
例えば128×128ピクセルのテクスチャ画像を表示するには、 128×128×16bit=262144bit=32KB の情報量で済みます。
なんと、フルカラー画像の半分ですね。
当然ですが、情報量が減れば、実際にプログラムが画面表示に必要とするメモリー量も、ユーザーがダウンロードするファイルサイズも、大きく削減できます。これは非常に重要なことですよね。
なお一般的に、このようなRGBA各4bitの16bitカラーのことを「RGBA4444」と呼びます。同様に、前述のフルカラー画像(32bitカラー)は「RGBA8888」です。
Unityに取り込むと画質が落ちるのはなぜ?
Unityでは、テクスチャ画像を16bitカラーに変換して取り込むときに、画像の各ピクセルのRGBA値を自動変換しています。その変換方法は非常に簡単で、「16段階ごとにひとまとめにしていく」だけです。
数字で現すと、こうなります。
8bit(256階調)値 | 0 1 2 ... 14 15 | 16 ... 31 | ... | 240, ... 255 | ↓ 4bit(16階調)値 | 0 | 1 | ... | 15 |
例えば、なだらかな256段階のグラデーションを描いたフルカラー画像が、Unityで16bitカラーに変換すると、16階調の階段状の色に変化してしまうのです。
サンプル画像をご覧いただくと、良くわかると思います。
→ | ||
フルカラー画像 (32bit RGBA8888) |
Unityと同じ方法で 16bitカラーに変換した画像 (16bit RGBA4444) |
このように、なめらかだったグラデーションが、段々畑のような縞模様のようになってしまいます。
なお、このような縞模様はよく「バンディング」や「マッハバンド」と呼ばれています。
それでは、キレイに16bitカラーにする方法は無いの?
ここまでの説明を見る限り、「これでは、どうしようもないのでは」と思われるでしょう。なにしろ、フルカラー画像(RGBA8888)では8bit(256階調)だった情報が、16bitカラー画像(RGBA4444)では4bit(16階調)にまで減ってしまうわけです。これでは、画質が落ちるのも仕方が無さそうに見えますね。
ところが実は、Unityでもっとキレイに16bitカラーに変換する方法があるのです。
発想を変えてみましょう。
「どうせ4bitに削られてしまう情報なのだから、あらかじめ、4bitでもキレイに見えるように加工してからUnityに取り込めば良い」のです。
誤差拡散を使ってみる
画像の表現テクニックの一つに、「誤差拡散」というものがあります。「ディザリング」と言ったほうがわかる方もいるかもしれません。
例えば、赤のピクセルと、緑のピクセルを、交互に市松模様のように並べると、どんなふうに見えるでしょう。
+ | → | |||
赤 | 緑 | 赤と緑を交互に並べたもの |
どうでしょう、2色の中間の色に見えませんか?
更に、この2色の密度を変えて、赤を多目にしたり、緑を多めにしてみましょう。
2色の密度を変える
たった2色のはずなのに、一気に表現力がアップしましたね。2色を混ぜるようにピクセルを並べることで、その中間の色を疑似的に表現できるのです。これが、「誤差拡散」の考え方です。
では、先ほどの「Unityに取り込むと画質が落ちるのはなぜ?」のフルカラー画像を、誤差拡散を使って中間階調を表現した16bitカラー画像へ変換してみましょう。変換には、当社製品の「OPTPiX imésta 7 for Mobile & Social」を使用しています。
→ | ||
フルカラー画像 (32bit RGBA8888) |
誤差拡散を使った 16bitカラー画像 (16bit RGBA4444) |
同じ16bitカラー画像なのに、先程のときのようなバンディング(マッハバンド)が目立たず、ずっとキレイに見えませんか?
この、変換後のテクスチャ画像を、Unityに取り込んでみたらどうでしょう。
誤差拡散を使って変換してからUnityに取り込んでみる
それでは、誤差拡散を使った16bitカラー画像へ変換してから、実際にUnityに取り込んで見比べてみましょう。
→ | ||
フルカラー画像 (32bit RGBA8888) |
Unityで16bitカラーに変換して取り込み、 画面表示した場合(画面キャプチャ) |
→ | ||
誤差拡散を使った 16bitカラー画像 (16bit RGBA4444) |
あらかじめ16bitカラーに変換してから、 Unityに取り込んで、画面表示した場合 (画面キャプチャ) |
このとおりです。あらかじめ誤差拡散を使った16bitカラーへ変換しておくことで、無加工のままUnityに取り込むよりも、ずっとキレイに表示できるようになりました。これが、Unityでキレイなテクスチャ画像を使う方法です。
さいごに
ではこのように、フルカラーのテクスチャ画像を、キレイな16bitカラー画像に変換するには、どうすれば良いのでしょう。
この解説のサンプル画像では、当社製品の「OPTPiX imésta 7 for Mobile & Social」(以下、OPTPiX imésta) を使用しています。
OPTPiX imésta には、「イメージ変換」という、今回紹介したような誤差拡散処理を搭載しており、キレイな16bitカラー画像への変換を実現していす。
ご興味を持たれた方は、無料で全機能をお試しいただける「フルトライアル版」もありますので、この機会に是非ともその効果をご確認ください。
おまけ
実際に、OPTPiX iméstaの「イメージ変換」を使用してUnityへテクスチャ画像を取り込む手順は、以下のようになります。お使いになるときの参考にしてください。
- 変換したいテクスチャ画像を OPTPiX imésta で開きます。
- 「イメージ」メニューの「イメージ変換」を選びます。
- 「イメージ変換」ダイアログが開くので、以下のように設定し、[OK]ボタンを押すと、変換が実行されます。
- 「変換形式」は「RGB」
- 「レンダリング処理」は「ノーマル誤差拡散」
- 「変換するRGB階調」は、アルファ付きなら「RGBA4444: 16bit」、アルファ無しなら「RGB565: 16bit」
- 変換後の画像ウィンドウを選択し、「ファイル」メニューから「名前を付けて保存」を選びます。
- 保存ファイル名を指定します。
- 「ファイルの種類」は「PVRファイル」を選びます。
- 「ファイル保存オプション – PVR」というダイアログが開くので、「テクスチャ形式」で以下のように選択し、[OK]ボタンを押すと、PVRファイルに保存されます。
- アルファ付きなら「ARGB4444: 16bit」、アルファ無しなら「RGB565: 16bit」
- このPVRファイルを、Unityに取り込んでください。
大量にテクスチャ画像がある場合は、「マクロ」メニューの「マクロ処理」を使うと、一括で変換できます。設定内容は上記と同じです。こちらも併せてお試しください。
それではまた。