Unityレンダリング最適化に関して、あう可能性のある問題――レンダリング編（壱）

##キーワード
Draw Call
半透明オブジェクトのレンダリング

---
##一、Draw Call相関
Q1: モバイルゲームのシーンに、モンスターが同じ場合、Draw Callは動的バッチ処理をしますか？次のような設定できますか？
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/d4b0cc0d-f3b4-c82a-3f9b-f3770f14198a.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/29380064-65e7-6dcb-5a86-0050442f3e4e.png)
>デフォルトでは、スキン付きMeshは動的バッチ処理をサポートしていません。シーン内にマテリアルの同じスキンメッシュがたくさんある場合は、プラグラインMeshBakerを介してバッチ処理することを考えられます。具体的には[「人気のプラグインの紹介（アセット編）」](https://blog.jp.uwa4d.com/wp-admin/post.php?post=984&action=edit)を参照してください。

---
Q2: Draw CallとSetpass Call、これら2つの指標のどちらを注目する方が良いですか？この点について色々な意見が分かれており、SetPass Callについては多くの場所で話題になっていますが、UWAのパフォーマンステストでは、依然としてDrawCallが唯一の指標と見なされています。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/80cfa6e6-bfed-882f-61fd-7c9db804ddd8.png)
>Unity 5.xでは、Draw Callと比べると、SetPass Callの指標はパフォーマンスにより大きく関連しています（たとえば、Static BatchingをオンにするとDraw Callに影響しませんが、SetPass Callは通常大幅に低下します）。ただし、SetPass Callにも問題がある場合があります。たとえば、１つのシーンに任意数の同じマテリアルを持つ隣接する大きなメッシュを添付する（Dynamic Batchingを無効させ）時、SetPass Callは変更しません。ですから、UWAでは、ProfilerにあるTotal Batchesのような指標を採用しています。通常、この値は基本的にFrame Debuggerにある数値と同じです。だからこのツールで各Batchの内容を確認でき、対処して最適化できます。

---
Q3:UWAレポートの「レンダリングモジュール」インターフェースで、ほとんどのシーンの三角形の面数は正常であることがわかりますが、あるフレームでDrawCall、Traingle、およびスキニングメッシュは突然増加します。可能の原因はなんですか？この三つのパラメーターの変化曲線は規則的ですか？シーンを切り替えるときも400以上のDrawCallがあるのはなぜですか？
![4-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/1ec30054-f947-b8e5-1704-a5353d9c3bef.png)
>画像から見ると。この状況はシーンの切り替えところで発生します。大量のGameObejctを一回で動的ロードし、手動で不要なGameObjectをDeactiveすることが問題を引き起こす可能性がかなり高いです。開発チームはこのピークのシーン名と関するスクリーンショットを確認でき、問題の根本原因をさらに特定できます。

---
Q4：Static Batchingに関します。シーンにあるオブジェクトが大きいMeshに合併する時、サブMeshが大きいMeshに合併するかどうかを判断する根拠は何ですか？マテリアルですか？Staticをチェックすることですか？
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/82ece418-c955-6ce1-1a62-a2ac0f960073.png)
Aというモデルがあり、Staticをチェックし、マテリアルAを使用し、他のマテリアルのMeshと一緒に合併したかどうかをどうやって確認できますか（Combined Mesh）？
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/f275fc92-84e1-1bb8-9cef-9da932e17550.png)
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/1e20bb81-ef7c-3776-e5e6-29ec09741e8f.png)
>StaticをチェックするGameObjectにあるMeshはすべてCombineMeshに合併します（マテリアルに関係なく）。そして各MeshはSubMeshとして存在します。Unity 5.3より前は、レンダリング手順が隣接するマテリアルの同じSubMeshに対して、動的にそれらのインデックス配列を結合させ、１つのDraw Callに合併します。しかし、Unity 5.3以降に、マテリアルを切り替えないと作成された複数のDrawCallのコストが大きくなく、１つのBatchに統計されるため、インデックス配列を結合させなくなりました。

---
Q5: UnityがDynamic Batchingの数量に制限ありますか？あるいは、Saved by Batchの数量に対する制限ありますか？
>
Unityには、どのメッシュ面に対しても65536の制限があり、合併後のファセット数についても同じです。

---
Q6: 質問です。キャラクターはパートごとに服装変更できますか？たとえば、服とズボンを別れるように、両者もSkinned Mesh Renderを採用していますから、合併してDraw　Callを減らす方法はありますか？
>
DrawCallを減らす効果は、Meshを合併する方法で実現できます。具体的にはAsset Storeにある服装変更の例を参照してください：Character Customization。ただし、キャラクターが変装する時に以下の点に気ついてください。
（1）装備とキャラクターはボーンのセットを共有する必要があります。
（2）各装備の間に使用されるマテリアルは同じでなければなりません。
開発者は、上記の2つの条件が同時に満たされた場合にのみ、少量のDraw Callを使用して動的変装効果を行えます。

---
Q7: Canvasにあるものが画面の外に移動された後、DrawCallは減らしないので、それでもフレームごとに描画しますか？
>
DrawCallは減少しないことは、CPUは依然としてこの部分のメッシュをGPUに提出したということです。ですから、CPUコスト（レンダリング状態の切り替え、VBOの提出など）はまだありますが、最終的にピクセルのレンダリングは行われないため、GPUへの影響はあまりありません。

---
Q8: NGUIのレンダリング効率を改善するためのアイデアをいくつか提供できますか？
>
開発チームは、以下の点から始めることができます。
1、通常、1つのPanelは１つまたは複数のDraw Callを作成します。 Panelを単位として、Draw Callの数量は一般的に使用されているAtlasとFontの数量によって決まります。
2、UIレンダリング する時のDrawCall数を減らしたいと、Atlasの作成に合理的な計画を立てる必要があります。つまり、使用するAtlasを少なくすると同時に、Atlas間に相互オクルージョンがないことを確認する必要があります。
3、UI Textureの使用に注意してください。各UITexture自体が１つのDraw Callを占めます。同時に、Depth値が同じAtlasからの他のUISpriteに散在している場合、Draw Callの中断を導き、不要な追加Draw Callを引き起こします。
4、さらに、Panel ToolとDraw Call Toolを使用してUI部分のDraw Callを分析できます。前者は各UIPanelに含まれるDraw Callの数を表示でき、後者は各Draw CallがどのUIWidgetで構成されているかを表示できます。

---
Q9: シーンにあるプレイヤーとNPC名のDrawCallに関する質問です。プロジェクトでTextMeshを使ってシーン単位に掛けますが、これで各名前は１つのDrawCallを占有します。それを最適化する良い方法はありますか？
>
ゲーム内のHUDには、一般に2つのやり方があります。１つは上記とおりです。もう１つはNGUI/UGUIを介してHUDを作成することです。２つ目の方法は大体下記のように、
1、画面上のキャラクターの位置を計算します。
2、画面上の位置に応じて各HUDの位置を計算し、HUDの数に応じて1つまたは複数のPanel/Canvasの下に配置します。
>
2番目の方法の利点は、できるだけに少ないDraw Call数でキャラクターのHUDをレンダリングできます。開発チームはこの方法を試すことができます。

---
##二、半透明オブジェクトのレンダリング
Q1: このバッチレンダリングとは何ですか？ オーバーヘッドが高いようです。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/197c05bd-cbd5-3709-ea45-5f1481f76147.png)
>この画像を見ると、これはシーンにある不透明オブジェクトのレンダリングコストであることがわかります。当該シーンにある不透明オブジェクト（地形、建築物など）に更に検査することを開発チームにお勧めします。主に三角ファセットの数は多すぎるかどうか、またはShaderは複雑すぎるかどうかを確認する必要があります。

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

今なら、UWA GOTローカルツールが**15日間に無償試用**できます！！
よければ、ぜひ！

UWA公式サイト：https://jp.uwa4d.com
UWA GOT OnlineレポートDemo：https://jp.uwa4d.com/u/got/demo.html
UWA公式ブログ：https://blog.jp.uwa4d.com