Unityシーン容量削減勉強会 第3回 ～モデル編～

# Unityシーン容量削減勉強会 第3回 ～モデル編～

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

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

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

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

# Project Settingsを見てみよう！

まずは、 `Project Settings` にある `Vertex Compression` を見てみましょう！

## Vertex Compression

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/721a2660-e3b9-5dd2-25da-81b999dcbc96.png)

`Project Settings > Player > Other Settings > Optimization` の中に `Vertex Compression` という項目があります。

これは頂点情報の圧縮に関する設定で、プロジェクト内の **すべてのメッシュ** に影響します。
（あくまでビルド時に利用するものであり、元のメッシュファイルに影響はありません）

なお、 **頂点の数は減りません！**
位置やUVといった、頂点1つ1つが持つデータの精度（座標値の桁数）が減ります。

以下の項目があり、 **チェックをつけた項目は、容量を半分に削減できますが、精度も落ちます。**

| 項目名         | 初期値 | 内容 |
|:--------------|:---:|:---|
| `None`        | 🔲 | 何も圧縮しません。 |
| `Everything`  | 🔲 | 以下のすべてを圧縮します。 |
| `Position`    | 🔲 | 位置。圧縮すると外見に大きな影響を与える可能性があります。 |
| `Normal`      | ✅ | 法線 |
| `Tangent`     | ✅ | 接線 |
| `Color`       | 🔲 | カラー（テクスチャではなく頂点カラーのこと） |
| `Tex Coord 0` | ✅ | メインのUV。一般にカラーテクスチャーやノーマルマップに使われます。 |
| `Tex Coord 1` | 🔲 | サブのUV。いわゆるUV2。一般にライトマップに使われます。 |
| `Tex Coord 2` | ✅ | 予備のUV |
| `Tex Coord 3` | ✅ | 予備のUV |

チェックをつけた項目は、精度が `FP32` から `FP16` になります。
容量を半分に削減できますが、精度も若干悪くなるので、 **見栄えとパフォーマンスのトレードオフ** になります。

### FP32とFP16の違い

`FP32` と `FP16` はどちらも、コンピューターが実数（浮動小数）を表現するためのデータ形式です。
以下のような違いがあります。

| データ形式 | 容量 | 表現可能な範囲 |
|---|---|---|
| FP32 | 32bit | 1.4 x 10^{-45} ～ 3.4 x 10^{38} |
| FP16 | 16bit | 5.96 x 10^{-8} ～ 65504 |

### スキンメッシュにVertex Compressionは効かない

スキンメッシュには、 `Vertex Compression` は効かないので、ご注意ください。
スキンメッシュとは、ボーンを動かすと連動して変形するメッシュのことで、たとえばアバターが当てはまります。


# モデルの設定を見直そう！

次に、モデル毎の設定を見直しましょう！
FBX等のモデルファイルを選択すると、 `Inspector` ウィンドウに以下のような設定項目が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/439a2cc4-218e-f4bf-d65e-3d2f68b30469.png)

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

今回はこの中で、容量削減に効果がありそうな項目を紹介します。

## Import BlendShapes

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/1e950259-0511-2c16-abcb-6059fdff3956.png)

`Import BlendShapes` は、ブレンドシェイプをインポートするかどうかの設定です。

**ブレンドシェイプを使わないモデルは、 `OFF` にすることで容量を削減できます！**

### ブレンドシェイプとは？

ブレンドシェイプとは、メッシュの頂点を動かしてアニメーションさせる技術です。
キャラクターの表情や口の制御によく使われます。

以下の図は、ブレンドシェイプで口の形が変化している様子です。
左から `a` `i` `u` `e` `o` のブレンドシェイプを適用しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/91e68172-204c-9472-99d4-c7e92911ca98.png)

## Mesh Compression

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/453f0a88-a37a-854f-6695-9dc8f23edb01.png)

`Mesh Compression` は、メッシュ毎に圧縮レベルを決めるための設定です。

プロジェクト全体の共通設定である `Vertex Compression` よりも、メッシュ毎の個別設定である `Mesh Compression` の方が、優先されます。

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

| 値       | 容量 | 品質 | 位置の<br>圧縮率 | 法線の<br>圧縮率 | 接線の<br>圧縮率 | UVの<br>圧縮率 | カラーの<br>圧縮率 |
|:---------|:---:|:----:|----:|----:|----:|----:|----:|
| `Off`    | 最大 | 最高 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
| `Low`    | 大  | 高    | 1.6 | 4.6 | 4.4 | 2.0 | 1.0 |
| `Medium` | 中  | 中    | 2.0 | 5.6 | 5.3 | 3.2 | 1.3 |
| `High`   | 小  | 低    | 3.2 | 7.4 | 6.7 | 4.0 | 2.0 |

なお、 `Mesh Compression` を使っても、 **頂点の数は減りません！**
位置やUVといった、頂点1つ1つが持つデータの精度（座標値の桁数）が減ります。

| `None` | `Medium` | `High` |
|---|---|---|
| 無圧縮 | 容量は `None` の約40% | 容量は `None` の約30% |
| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/955aa8cc-4bc2-3148-52d6-804c5d9242e3.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/adb1cb28-bbdc-a909-7802-cc90630b2c1b.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/23eb80a0-57c8-fa1f-4a43-adb162b068fe.png) |
| 図転載: [Reducing build sizes in Unity3D](https://suraj.dev/blog/reducing-build-sizes-in-unity3d) |

上図のように、 `High` に行くほど容量を削減できますが、品質も低下してしまうので、 **見栄えとパフォーマンスのトレードオフ** になります。



## Legacy Blend Shape Normals

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/d052006a-4c31-9f74-c166-866ab6277f62.png)

`Legacy Blend Shape Normals` は、ブレンドシェイプの法線に関する設定です。

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

| `Legacy Blend Shape Normals` の値 | 法線の計算方法 |
|:---:|---|
| `ON`  | 古い方法が有効になります。 |
| `OFF` | 新しい方法（ `Blend Shape Normals` ）が有効になります。 |

Legacyという名前通り、古い方法を有効にするための設定項目なので、強いこだわりがなければ **OFFにした方がいいです。**
その代わりに、次項で説明する `Blend Shape Normals` を適切に設定しましょう。

## Blend Shape Normals

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/301877f2-2e24-5790-5daa-fda52358a9ca.png)

`Blend Shape Normals` は、ブレンドシェイプの法線に関する設定です。
`Legacy Blend Shape Normals` を `OFF` にすると、設定できるようになります。

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

| 値 | 容量 | 機能 |
|:---:|---|---|
| `Import`    | 大 | モデルが保有しているブレンドシェイプ毎の法線を使用します。<br>モデリングソフトで作成した法線をそのまま使いたい場合に選択します。 |
| `Calculate` | 大 | Unityがブレンドシェイプ毎に法線を自動で計算します。 <br> 具体的には、 `Normals Mode` `Smoothness Source` `Smoothing Angle` の値にしたがって計算します。<br> `Legacy Blend Shape Normals` よりも洗練されたアルゴリズムらしいです。 |
| `None`      | 小 | ブレンドシェイプ毎の法線を使用しません。<br>すべてのブレンドシェイプで共通の法線を利用します。 |

**ブレンドシェイプを使わないモデルは、 `None` を選んで容量を削減しましょう！**

すべてのブレンドシェイプで共通の法線を利用しても問題ないと判断した場合も、 `None` を選ぶと容量を削減できます。


# Unity以外でやれること

ここまでUnityの設定項目を紹介してきましたが、どうしても大味な対処になりやすく、限界があります。
Blender等のモデリングツールが使えるのであれば、以下のような手法により容量削減ができるかもしれません。

## 不要なデータを削除する

ストア等で販売されているアセットは、さまざまな用途でも利用できるように、多くのデータを含んでいます。以下のようなものです。

- メッシュ
- 法線
- 接線
- UV
- 頂点カラー
- ボーン
- スキンウェイト
- ブレンドシェイプ

ご自身が作っているUnityシーンに、上記すべてのデータが必要か？というとそうではないことが多いです。
**不必要なデータは、Unityに取り込む前に削除しておく** ことで、容量を削減できます。

## 頂点数を削減する

ここまで触れてきませんでしたが、容量削減効果が非常に高い方法として、 **頂点数削減** があります。

頂点数が必要以上に多いメッシュは、頂点数を削減すべきです。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/448c5091-3497-5dd2-bb02-f3daa4357a9e.png) |
|---|
| 図転載 [【Blender3.1】面/頂点を削減：デシメートモディファイアー](https://cgbox.jp/2022/04/16/blender-decimate/) |


ただ、**外観が崩れてしまうリスクが高いため、繊細な配慮と高度な知識を必要とします。**

有料・無料含め多くのツールや手法があり、この場では語り尽くせないため、解説を省略いたします！
検索すると、素晴らしい記事がいくつも見つかりますので、そちらをご参照ください！

# さいごに

今回はここまでです！
次回はアニメーション編です！よければそちらもお読みください！

https://qiita.com/segur/items/071e228258806f3e0113

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

- [Unity Documentation / Model タブ](https://docs.unity3d.com/ja/2019.4/Manual/FBXImporter-Model.html)
- [Unity Documentation / メッシュデータの圧縮](https://docs.unity3d.com/ja/2021.3/Manual/mesh-compression.html)
- [Unity Documentation / ファイルサイズの削減](https://docs.unity3d.com/ja/2019.4/Manual/ReducingFilesize.html)
- [UNITY アプリのビルドサイズ容量削減する方法 総まとめ](https://techblog.unitedcube.com/unity/unity_build_size_down/)
- [Unity で作ったアプリのサイズを減らす 20 の方法【Unity】【容量削減】](https://kan-kikuchi.hatenablog.com/entry/Unity_App_Size)
- [容量削減ノウハウ](https://summer2022.vket.com/docs/submission_tips_capacity)
- [Unityでカスタム法線メッシュにブレンドシェイプを適用した際に法線が崩れる問題の解決法](https://qiita.com/ApricotLemon/items/221cbd85b8e149e832c0)
- [【Unity】実践的なパフォーマンス分析と最適化](https://tsubakit1.hateblo.jp/entry/2018/06/09/235351)
- [モデルデータの書き出しサイズを小さくする Mesh Compression](https://unitygeek.hatenablog.com/entry/2016/09/15/151120)
- [【Blender3.1】面/頂点を削減：デシメートモディファイアー](https://cgbox.jp/2022/04/16/blender-decimate/)
- [Reducing build sizes in Unity3D](https://suraj.dev/blog/reducing-build-sizes-in-unity3d)