Unityシーン容量削減勉強会 第2回 ～テクスチャ編～

# Unityシーン容量削減勉強会 第2回 ～テクスチャ編～

本記事は、シーン容量削減勉強会の第2回の資料ですが、第1回を読んでいなくても問題ありません！
興味があれば、第1回も読んでいただけると嬉しいです！

##### Unityシーン容量削減勉強会シリーズ

- [Unityシーン容量削減勉強会 第1回 ～容量順でソートする編～](https://qiita.com/segur/items/c766b0512ab51b6bed4a)
- Unityシーン容量削減勉強会 第2回 ～テクスチャ編～ ← 本記事
- [Unityシーン容量削減勉強会 第3回 ～モデル編～](https://qiita.com/segur/items/550af881e7e8d5470b92)
- [Unityシーン容量削減勉強会 第4回 ～アニメーション編～](https://qiita.com/segur/items/071e228258806f3e0113)


# テクスチャの設定を見直そう！

スペックの高くない視聴端末でも快適に動作するように、Unityシーンの容量を削減することは重要です。
大抵のUnityプロジェクトでは、テクスチャが容量の大部分を占めるので、テクスチャは積極的に軽量化しましょう！

テクスチャファイルを選択すると、 `Inspector` ウィンドウに以下のような設定項目が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/79987646-8b49-5095-1b4b-e061001d5e37.png)

今回はこれの解説をします。

これらの設定項目はあくまでビルド時に利用するものであり、変更しても元のテクスチャファイルに影響はありませんので、気軽に変更していろいろ試してみましょう！

# オススメの値

結論を知りたい人向けに、オススメの値を掲載しておきます。

| プロパティ                  | オススメな設定        |
| ------------------------ | ------------------ |
| `Alpha Source`           | 不透明画像なら `None` <br>グレースケールマスクなら `From Gray Scale` <br>それ以外は `Input Texture Alpha` |
| `Generate Mip Maps`      | UI用画像なら `OFF` <br>それ以外は `ON`    |
| `Max Size`               | なるべく `1024` 以下  |
| `Resize Algorithm`       | `Mitchell`         |
| `Format`                 | `Automatic`        |
| `Compression`            | `Normal Quality`   |
| `Use Crunch Compression` | `ON`               |
| `Compressor Quality`     | `50`               |

順番に解説します。

# 現状のビルド後容量を確認する

`Inspector` ウィンドウの下の方にテクスチャ画像がプレビューとして表示されています。
さらによく見ると、下図の赤字のように容量が表示されています。これが現状のビルド後容量です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/086a78ea-78a7-752e-1a2e-68dc5f98523f.png)

このプレビュー画像と容量を参考にしながら、調整していきましょう！

# Alpha Source

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/8eab1c77-ea64-6de1-a378-8b3d19dcf945.png)

`Alpha Source` は、テクスチャの不透明度をどこから取得するのか指定するオプションです。

| Alpha Source          | 機能                   | 容量  | 用途例          |
| --------------------- | --------------------- | :--: | ----------- |
| `None`                | 透過なし                | 低   | 不透明画像   |
| `Input Texture Alpha` | Aチャンネルから不透明度を取得 | 高   | 透過PNG画像 |
| `From Gray Scale`     | RGBの平均値から不透明度を取得 | 低   | グレースケールマスク |

```mermaid
graph LR
    subgraph RGBAカラー
        R
        G
        B
        A
    end
    subgraph グレースケール
        GrayScale[RGBの平均値]
    end

    R -->|平均化| GrayScale
    G -->|平均化| GrayScale
    B -->|平均化| GrayScale

    subgraph "Input Texture Alphaの場合"
        A -..-> Alpha1[不透明度]
    end
    subgraph "From Gray Scaleの場合"
        GrayScale -.-> Alpha2[不透明度]
    end
```

**透明度を利用しない場合、 `None` を選択** して容量を削減しましょう！

以下のようなグレースケールのマスク画像の場合は、 `From Gray Scale` を選択しましょう！

![DissolveTexture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/b54f67a4-bab5-c36e-7d23-75e3d23d21c8.jpeg)

# Generate Mip Maps

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/924a655e-135e-af39-c649-44c0046b0619.png)

`Generate Mip Maps` は、ミップマップを生成するかどうか決定します。

ミップマップとは、元のテクスチャの1/2の大きさ、1/4の大きさ、1/8の大きさ、といった具合に縮小していった一連の画像ファイル群です。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/7e410941-134a-fad9-b1d7-eb15ddc9865b.png) |
|---|
| 図転載: [Unity Documentation / ミップマップの基本](https://docs.unity3d.com/ja/2021.3/Manual/texture-mipmaps-introduction.html) |

高解像度のテクスチャが遠くにあると、ジャギーが発生するという問題があります。遠い物ほど小さい解像度の画像を使用することで、このジャギーを抑えられます。
加えて、描画負荷を軽減する効果もあります。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/64b347a6-56f7-4349-957c-b95b4739665e.png) |
|---|
| 図転載: [Wikipedia / Mipmap](https://en.wikipedia.org/wiki/Mipmap) |

ただし、ミップマップは元テクスチャとは別に保管しなければならないので、シーン容量が増えてしまう問題があります。
そのため、遠くに描画することがないテクスチャは、ミップマップを使わない方が容量を削減できます。

たとえば、 **UI 用の画像は、** ユーザーから離れた位置に描画することがないため、 **ミップマップをOFFにしましょう！**

# Max Size

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/b4a9853b-c35b-3df9-4eba-89cae97848c5.png)

`Max Size` は、テクスチャの最大解像度です。

元のテクスチャの解像度が **`Max Size` で指定した値よりも大きい場合** 、Unityはテクスチャを `Max Size` の値に **縮小** します。

```mermaid
graph LR
    A[元解像度<br>1024] -->|Max Size<br>512| B[ビルド後解像度<br>512]
```

逆に、元のテクスチャの解像度が **`Max Size` で指定した値よりも小さい場合** 、 `Max Size` を大きくしてもテクスチャの **品質は向上しない** ので、ご注意ください。

```mermaid
graph LR
    A[元解像度<br>256] -->|Max Size<br>512| B[ビルド後解像度<br>256]
```


`Max Size` が小さいほど容量は減りますが、画質も低下するので、 **見栄えとパフォーマンスのトレードオフ** になります。

`32, 64, 128, 256, 512, 1024, 2048, 4096, 8192` の選択肢があります。
2のべき乗になっているのは、GPUが効率的に処理できるからです。

## Max Sizeをどのくらいにすべきか？

どのくらいの値にすべきか？は、テクスチャの用途によるので、一概には言えません！

ただ、あくまで私の感覚的には `2048` 以上の場合は、本当にその解像度が必要なのか確認したくなります。


## 低解像度でも問題になりにくい画像

人間は明度の変化には敏感ですが、色や透明度の変化には鈍感だと言われているので、以下のような画像は低解像度でも問題になりにくいです。

### 例: グラデーション画像

以下のような画像は、明暗の変化が激しくないので、低解像度にしても問題にはなりにくいです。

<img width="256" height="256" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/30e90e67-2fc8-e5c5-fa56-a8e087bc3679.jpeg" />

### 例: グレースケールマスク画像

人は透明度の変化には鈍感だと言われているので、以下のようなグレースケールマスク画像は、低解像度にしても問題にはなりにくいです。

![DissolveTexture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/b54f67a4-bab5-c36e-7d23-75e3d23d21c8.jpeg)


# Resize Algorithm

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/f6fd0fee-f6e9-fd93-9b67-9d9cc12e53ec.png)

`Resize Algorithm` は、テクスチャ解像度を縮小する際に使用するアルゴリズムです。

以下の2つの選択肢があります。

| `Bilinear` | `Mitchell` (Mitchell-Netravali) |
|:---:|:---:|
| 双一次補間 | 双三次補間(Bicubic)の一種 |
| ![blog142_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/eff46849-f5e4-49cb-abcc-b08d980d6b7f.png)| ![blog142_61.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/8e894809-41ae-8319-ae73-7b9ad269be1f.png) |
| 周辺2x2の色を元に色を決定 | 周辺4x4の色を元に色を決定 |
| ![blog142_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/e05aa3ed-7b88-1c11-53be-28a2ff14bcea.png) | ![blog142_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/98c1a985-a8a0-859e-7e64-7daa6e9d7de3.png) |
| ギザギザになりやすいが、シャープさは保持しやすい。 | なめらかになりやすいが、ぼやけやすい。 |
| 図転載: [画素の補間(Nearest neighbor,Bilinear,Bicubic)の計算方法](https://imagingsolution.net/imaging/interpolation/) ||

上記の転載画像は拡大表示時のものであり、違いがわかりやすいのですが、テクスチャ縮小時はここまではっきりとした違いは出にくいです。
どちらの縮小も試してみたのですが、正直私には違いを認識できませんでした。

そのため、基本的にはデフォルトの `Mitchell` を選択していればよいと思います！

ただ、リンギング（文字等のコントラストの高い部分に不自然な輪郭が発生する現象）がもし発生して気になる場合は、 `Bilinear` に変えてみると改善するかもしれません。

# Format

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/3ad243a6-16a1-d07b-d86e-d3040dd075a0.png)

`Format` はピクセルの表現方法を決定します。
以下の選択肢があります。

| 形式         | R   | G   | B   | A   | bpp | 用途例   |
| ------------ | :---: | :---: | :---: | :---: | ----: | ----------- |
| `Automatic`  | -   | -   | -   | -   | -    | 下記の中から最適なものを Unity が自動で設定します。 |
| `Alpha 8`    | ❌  | ❌  | ❌  | 8bit | 8bit | マスク画像     |
| `RGB 24bit`  | 8bit | 8bit | 8bit | ❌ | 24bit | 不透明画像。いわゆる **true color** |
| `RGBA 32bit` | 8bit | 8bit | 8bit | 8bit | 32bit | 透過PNG画像 |
| `RGB 16bit`  | 5bit | 6bit | 5bit | ❌ | 16bit | `RGB 24bit` よりも容量を減らしたいとき。いわゆる **high color** |
| `R 16bit`    | 16bit | ❌  | ❌  | ❌  | 16bit | 高度マップ   |
| `R 8`        | 8bit | ❌  | ❌  | ❌  | 8bit  | グレースケール画像 |


いろいろ選択肢があって混乱しますが、 **`Automatic` が無難です！**

意図せず `RGBA 32bit` になっている場合があるそうですが、 **`RGBA 32bit` は非常に重たいので** 、透過画像ではないなら **避けるべき** です。

グレースケール画像なら、 `R 8` を選択するのもアリだと思います。

# Compression

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/906b69b7-8ce7-5e77-6e4e-038441a7de10.png)

`Compression` は、テクスチャの圧縮タイプです。以下の4段階あります。

| 圧縮タイプ       | テクスチャ品質 | 容量 |
| ---------------- | :--: | :--: |
| `Low Quality`    | 低    | 少  |
| `Normal Quality` | 中    | 中  |
| `High Quality`   | 高    | 多  |
| `None`           | 最高  | 最多 

`High` よりも `Low` の方が、容量は減りますが画質も低下するので、 **見栄えとパフォーマンスのトレードオフ** になります。

`None` は圧縮をしないので画質は最高ですが、パフォーマンスが大幅に低下するリスクがあります。

# Use Crunch Compression

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/b7a579e5-afc1-e5be-6d91-d74591c58a97.png)

`Use Crunch Compression` はクランチ圧縮を使用するかどうかの設定です。
`Compression` が `None` 以外だと設定できます。

GPUはJPEGやPNG形式のファイルをそのまま読み込めないので、テクスチャはDXTCやETCといったGPUに特化した形式に変換されます。

クランチ圧縮は、そのDXTCやETCをさらに圧縮する仕組みです。

一部のディティールが失われることがありますが、全体の品質を維持したまま、 **大幅に容量を削減** できます！


# Compressor Quality

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/da0b8bec-9c28-a103-e466-d7382c682568.png)

`Compressor Quality` はクランチ圧縮の品質です。
`Use Crunch Compression` にチェックが入っていると設定できます。

数字が大きいほど、テクスチャの品質は上がりますが、容量も大きくなるトレードオフがあります。

私がいろいろと検索してみたところ、 `50` に設定している人が多いようです。

# さいごに

今回はここまでです！おつかれさまでした！

次回はテクスチャ編です！引き続きこちらも実践していただけると嬉しいです！

https://qiita.com/segur/items/550af881e7e8d5470b92

本記事は、以下のページを参考にさせていただきました。ありがとうございました。

- [Unity Documentation / テクスチャのインポート設定](https://docs.unity3d.com/ja/2019.4/Manual/class-TextureImporter.html)
- [Unity Documentation / 推奨、デフォルト、およびサポートされているテクスチャ形式 (プラットフォーム別)](https://docs.unity3d.com/ja/current/Manual/class-TextureImporterOverride.html)
- [Unity Documentation / テクスチャ圧縮形式](https://docs.unity3d.com/ja/2021.2/Manual/texture-compression-formats.html#crunch-compression)
- [Unity Documentation / ミップマップの基本](https://docs.unity3d.com/ja/2021.3/Manual/texture-mipmaps-introduction.html)
- [UNITY アプリのビルドサイズ容量削減する方法 総まとめ](https://techblog.unitedcube.com/unity/unity_build_size_down/)
- [Unity のテクスチャ圧縮について知ってること](https://priestly.fanbox.cc/posts/2677746)
- [画像を美しく加工するために押さえておきたいピクセルの知識](http://compojigoku.blog.fc2.com/blog-entry-15.html)
- [【Unity】Crunch 圧縮でロード時間は速くなるのか？](https://qiita.com/db0091/items/73f1171d8e3beb748854)
- [Unity で作ったアプリのサイズを減らす 20 の方法【Unity】【容量削減】](https://kan-kikuchi.hatenablog.com/entry/Unity_App_Size)
- [容量削減ノウハウ](https://summer2022.vket.com/docs/submission_tips_capacity)
- [画像リサイズのうんちく (補間フィルタ)](https://qiita.com/yoya/items/f167b2598fec98679422)
- [画素の補間(Nearest neighbor,Bilinear,Bicubic)の計算方法](https://imagingsolution.net/imaging/interpolation/)
- [Wikipedia / Mipmap](https://en.wikipedia.org/wiki/Mipmap)