Unity 5の新機能FrameDebuggerでグラフィックパフォーマンスを改善する

## 追記：2015年11月27日
本記事の旧タイトルは「Unity 5 Proの新機能FrameDebuggerでグラフィックパフォーマンスを改善する」でしたが、これは本記事がUnity 5リリース前に書かれたためで、Unity 5正式版は無料版PersonalでCloud、Team Licenseなどのアドオンを除くエディタ上の全機能が使用可能になったため、本記事から「Unity 5 Pro」の記述を取り除きました。

# Unityアプリのパフォーマンス最適化
UnityはMonoを採用しているため、C++やObjective-Cのようにネイティブのバイナリコードが出力されるわけではなくMono Virtual Machineで動作する中間言語が出力されそれを読み込んでアプリを実行しています。（iOSでは規約のためネイティブに事前コンパイルされています）
と言っても現在ではCPUの性能が向上し、Mono VMの効率も良くなっているためよっぽど無駄な処理を加えない限りCPUによるボトルネックはほとんど在りません。
リアルタイムのインタラクティブアプリケーションでは実際に絵を表示するGPUの最適化が非常に重要です。
Unityの公式マニュアルでも複数ページに渡ってまとめられているので、まだ読んだことが無い人は必ず確認しておきましょう。

[Unityマニュアル - グラフィックスパフォーマンスの最適化](http://docs-jp.unity3d.com/Documentation/Manual/OptimizingGraphicsPerformance.html)
[Unityマニュアル - 最適なパフォーマンスのためのキャラクター モデリング](http://docs-jp.unity3d.com/Documentation/Manual/ModelingOptimizedCharacters.html)

# Unityにおける**DrawCall**問題
さて、Unityでパフォーマンスの話をすると必ず出てくるものがDrawCall（ドローコール）です。
「最適化のためにDrawCallを減らしましょう。PCではxxxでモバイルではyyで〜」
という話はUnityで速度のことを意識している方なら聞いた事があると思います。
ですが、どう減らせば良いのか分からないことがあると思います。
公式マニュアルにもDrawCallを減らす方法は書いてありますが、これだけではどこをどう減らせばDrawCallを改善できるのか分からないでしょう。

[Unityマニュアル - DrawCall Batching](http://docs-jp.unity3d.com/Documentation/Manual/DrawCallBatching.html)
[Unityマニュアル - レンダリング統計 ウィンドウ](http://docs-jp.unity3d.com/Documentation/Manual/RenderingStatistics.html)

Statsボタンを押すと表示されるStatisticsウィンドウに描画の統計情報が表示されますが、これには最終結果の数字しか出ないため何がどう重い処理なのかも良く分かりません。（fpsの数字はCPU処理のものです）

![Unity5 Car](https://qiita-image-store.s3.amazonaws.com/0/11166/f20914ec-f3fa-c1af-b145-ad3d75b74da6.png)

* Unity 5の新サンプルシーンの一つ「Car」

![Unity5 Statistics](https://qiita-image-store.s3.amazonaws.com/0/11166/96a25da9-a682-fee2-ecf6-d3d3aef60817.png)

* Unity 5で一新されたStatistics(Stats)表示
  * Batchesは最終的なDrawCall数
  * SetPass callsはマテリアルへのDrawCall
  * Shadow castersは影の処理によるDrawCall (マテリアルに影を描画する処理も含むのでBatches−SetPass callsとは一致しない)

# UnityのProfilerでDrawCallの数を確認する
UnityにはProfilerというPro限定の機能があります。これはStatisticsと違いパフォーマンスに関するログを時系列でグラフ化し、フレームごとにどんな処理が行われたかの概要を表示してくれるものです。

![Unity Game View](https://qiita-image-store.s3.amazonaws.com/0/11166/f11a48a9-44c3-597d-56a5-47217060f91f.png)
Unity Standard Assetsのパーティクルを表示しただけのシーン

![Unity GPU Profiler](https://qiita-image-store.s3.amazonaws.com/0/11166/9b47d427-2adc-0310-1292-d7cd2fdbd69a.png)
Render.TransparentGeometry（半透明ジオメトリの描画）でDrawCallを5回実行し、6.15msかかっていることが分かりますが、画面にどのような過程で描き込まれているかまでは分かりません。

UnityのProfilerは非常に便利ですが、GPUのプロファイリングに関してはほぼDrawCallの数と処理時間が分かるだけでどう最適化すれば改善できるのかといった部分が分かりにくくなっていました。これを改善するのが次に紹介するFrame Debuggerです。

# Unity 5で追加されたFrame Debuggerを使う
Unity 5では新たに各フレームの描画過程を確認することが出来るFrame Debbugerが実装されました。
例えば上記のパーティクルのシーンでFrame Debuggerを使うと以下のようになります。

![Frame Debugger](https://qiita-image-store.s3.amazonaws.com/0/11166/4838cec2-c0e2-c3d9-f48f-41c4b3d08433.gif)

Game Viewを動かしている時でもFrame DebuggerのEnableボタンを押すことで瞬時にフレームの内訳をデバッグすることが出来ます。
今回の場合はパーティクルがどういう順番で描画されているのか、各パーティクルが何個の頂点(Vertices)を持っているのかといったこれまでのUnityでは不可視だった情報が表示されていることが分かるかと思います。

上のgifはあまりにもシンプル過ぎるので、今度は一番最初のCarシーンをFrame Debuggerで見てみましょう。容量が嵩むため高速で切り替えていますが、Frame Debuggerでどういう情報が見れるのかは分かると思います。

![](http://f.cl.ly/items/1X3w473B2B2i1n032l37/Frame5.gif)

* マテリアル単位でDrawCallを発行している様子を実際に確認出来る
* シャドウマップやImage EffectのためのDrawCallも確認可能

# 外部フレームデバッガーについて
Frame DebuggerはUnity 5の新機能ですが、GPUメーカーが出しているツールや最新のVisual Studioではフレームデバッガーも含まれています。これらを使ったデバッグも当然できるので、Unity 5が待てない方はこちらを試すのも良いでしょう。以下にUnity5のマニュアルで紹介されているツールを記しておきます。

* [Visual Studio graphics debugger](http://msdn.microsoft.com/en-us/library/hh315751.aspx)
* [Intel Graphics Performance Analyzer](https://software.intel.com/en-us/gpa)
* [NVidia NSight](http://www.nvidia.com/object/nsight.html)
* [AMD GPU PerfStudio](http://developer.amd.com/tools-and-sdks/graphics-development/gpu-perfstudio/)
* [RenderDoc](https://github.com/baldurk/renderdoc)

Unity Advent Calendar 3日目は@tsubaki_t1さんです。