【Unity】テクスチャを高品質な16bit画像でインポートできる「unity-dither4444」

Unityで使用するテクスチャについて調べていたら便利なスクリプトを見つけたのでメモ。

unity-dither4444:
https://github.com/keijiro/unity-dither4444

画像を16bitでインポートする時にディザリングをかけて画質の劣化を改善できます。

例として、この画像をUnityに取り込んでみましょう。

08(オリジナル画像)

この画像をUnity標準の「16 bit」でインポートする場合と、「unity-dither4444」を使ってインポートする場合で比べてみます。

DitherTest(左:Unity標準、右:unity-dither4444)

unity標準の「16 bit」でインポートした場合は、顔のグラデーション部分にマッハバンド(色が滑らかに変化しない)が出てしまっています。

また、地面の色や影の色も変わってしまいました。

一方、unity-dither4444でインポートした画像はディザリングを行っているため、少ない色数を分散して中間色を表現する事でオリジナル画像に近い見え方になっています。

unity-dither4444の使い方

まずはここからスクリプトをありがたくダウンロードさせていただきましょう。

unity-dither4444:
https://github.com/keijiro/unity-dither4444

必要なファイルは、「Assets」→「Editor」内の「TextureModifier.cs」です。

これをUnityの「Editor」フォルダに放り込みます(Editorフォルダが無ければ作成して下さい)

あとは、ディザリングを行いたい画像ファイル名の末尾を「Dither」に変更してインポートするだけで画像がディザリングされ、16bit形式に変換されます(インポーター上の表示はTruecolorになっていたりしますが実際はちゃんと16bitになっています)

 

ただし、このスクリプトをそのまま使うと不都合な場合があります。

例えば、初期状態のままだとインポートするテクスチャタイプが強制的に「GUI」になってしまったり、元画像のフォーマットがPNG形式の時しかディザリングは適用されません。

これらの問題について以下で解決していきます。

テクスチャタイプをGUIにしない方法

これについては配布元から説明がされているので引用させていただきます。

このサンプルではすべてのテクスチャが GUI 用途であるため、テクスチャタイプを “GUI” に変更する処理も行っています。これは簡便化のために挟んでいるだけで、本来は不要な処理です。

つまり、テクスチャタイプを強制的にGUIに変更する処理は削除してしまって構いません。

スクリプトの中身を開いて、11行目の当該箇所を修正します。

importer.textureType = TextureImporterType.GUI;

を削除するか、コメントアウトすればOKです。

なお、プロジェクトで使用するテクスチャタイプが一種類だけの場合は、この部分に任意のタイプを指定しておけば毎回選択する手間が省けます。

PNG以外の画像もディザリングする

このスクリプトは初期のままではPNG形式の画像しかディザリング対象として認識しないので、他の形式を追加してみましょう。

例えばフォトショップ形式「PSD」も扱えるようにしたい場合、13行目の

if (assetPath.EndsWith ("Dither.png")) {

if (assetPath.EndsWith ("Dither.png") || assetPath.EndsWith ("Dither.psd")) {

に変更して、さらに20行目の

if (!assetPath.EndsWith ("Dither.png")) {

if (!assetPath.EndsWith ("Dither.png") && !assetPath.EndsWith ("Dither.psd")) {

に変更します。これで末尾に「Dither」とつくPNG形式とPSD形式の画像ファイルを扱えるようになりました。

JPEG画像やGIF画像を追加したい時も同様に試してみて下さい。

 

なお、上記の条件式を全て外してしまえばファイル名に関係無く、全ての画像ファイルをディザリングして16bit変換するようにも出来ます。

また逆に、「ファイル名の末尾に指定の文字が入っている時だけディザリングしない」という処理にする事もできます。

それぞれの開発スタイルに合わせてカスタマイズしてみるといいと思います。

16bitにする理由

最後に、そもそも何故テクスチャを画質の悪い16bitに変換する必要があるのか説明します。

Unityでは使用する画像を様々な形式でインポートする事ができます。
すごく簡単にまとめると、こんな感じ。

  • Compressed: 画像を圧縮フォーマットに変換してインポートする
  • 16 bit: 画像を色数の少ない16bit colorに変換してインポートする
  • Truecolor: 画像を最高画質の32bit形式に変換してインポートする

Compressedはデータサイズが小さい代わりに画像が滲んだり、iOSとAndroidでフォーマットが異なっていたり、Androidではアルファチャンネルのある画像を圧縮できなかったりするらしいです。

また、Truecolorは画像を最高画質で表示する事ができますが、データサイズがかなり大きくなってしまいます。

じゃあ16bitがいいかというと、Unity標準の16bit変換では先ほども紹介したように著しく画質が悪化してしまいます。

という事で、せめて16bitをキレイに表示できないものかと頭を悩ませていたわけですね。

 

Unityの16bit画像についてはこちらのサイトで詳しく解説されているので紹介させて頂きます。

KAYAC DESIGNER’S BLOG:
Unityやるには必須!RGBA画像減色の基礎をまじめに書いてみた
http://design.kayac.com/topics/2014/02/unity-RGBA4444.php