渋谷ほととぎす通信

新しいこと、枯れたこと問わず大庭が興味を持ったものを調査、生活の効率を求める完全趣味の技術ブログ。基礎を大事にしています。

CEDEC2019気になったUnity情報パフォーマンス編


f:id:esakun:20190902025818p:plain CEDEC2019に聞き手として参加させて頂き「Unity2018/2019における最適化事情」セッションを元にパフォーマンス関連についてまとめます。

既存機能のアップデート

f:id:esakun:20190907223335p:plain:w450 既存機能アップデートに関するスライドですが、気になったものだけ取り上げて説明します。

AnimatorのGameObject非アクティブ化時のリセット対策

※Unity2018.1から対応

Animator.keepAnimatorControllerStateOnDisable APIのことでこれをtrueにすると非アクティブにしてもステートが残ります。デフォルトfalseで、非アクティブ時にステートのバッファをクリアしているようです。

Animator-keepAnimatorControllerStateOnDisable - Unity スクリプトリファレンス

ParticleSystemのGPU Instancing対応

※Unity2018.1から対応

通常WorkerThreadのParticleSystem.GeometryJobでParticleSystemのメッシュ結合処理をしています。CPU側でメッシュの結合をしてGPUに送り、パーティクルを表示させています。 f:id:esakun:20190907231343p:plain:w200

GPU Instancingを有効にすると、CPUで処理しているメッシュ結合がなくなり、GPU側でコピーされるようになり、処理の高速化が期待されます。
※GPU Instancingを有効化するとWorderThreadのGeometryJobはいなくなります。


RenderModeがMeshの時かつ、Enable Mesh GPU Instancingにチェックが入っていないとGPU Instancingは有効になりません。

f:id:esakun:20190907234958p:plain:w450

またUnityが用意しているシェーダ(Particle/Standard Unlitなど)なら対応していますが、自作で書いているものはそれに倣って修正する必要があります。

【Unity】パーティクルをGPU Instancingで描画してみる & 対応シェーダーを自作してみる - テラシュールブログ
詳しくはこちらの記事で。


PhysXのアップデート

f:id:esakun:20190907223350p:plain:w450

f:id:esakun:20190907214902p:plain:w450

スライド画像の通りです。

Profilerのアップデート

f:id:esakun:20190907215014p:plain:w450

上図のProfilerアップデート概要の通りProfilerが大規模にアップデートされています。
分かりやすいものは以下箇条書きしています。

  • Profilerのフレームが300から2000までアップ可能。Preferencesから設定する (Unity2019.3から対応)
  • IL2CPPビルドした実機でもDeepProfilingが可能 (Unity2019.3から対応)

特にIL2CPPビルド後のDeepProfilingは待ち望んでいました。(まだベータで使えないけど)


ここからは軽い説明付きです。

Hierarchyでメインスレッド以外が閲覧可

※Unity2019.3から対応

f:id:esakun:20190907225701p:plain:w450 このようにメインスレッド以外の状態をHierarchyから見れるようになりました。
(今までTimelineでしか確認することはできなかった)
ただし僕の環境(Mac & Unity2019.3.0b1)では、プルダウンを切り替えようとすると以下のヌルポが出て確認できませんでした。

NullReferenceException: Object reference not set to an instance of an object
UnityEditor.EditorWindow.Close () (at /Users/builduser/buildslave/unity/build/Editor/Mono/EditorWindow.cs:919)
UnityEditor.StatelessAdvancedDropdown.ResetAndCreateWindow () (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/AdvancedDropdown/EditorGUI/StatelessAdvancedDropdown.cs:21)
UnityEditor.StatelessAdvancedDropdown.DoLazySearchablePopup (UnityEngine.Rect rect, System.String selectedOption, System.Int32 selectedIndex, System.Func`1[TResult] displayedOptionsFunc, UnityEngine.GUIStyle style) (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/AdvancedDropdown/EditorGUI/StatelessAdvancedDropdown.cs:125)

ProfilerReader

Unity黒河さん作のアセット。
ProfilerのログをCSV書き出しをしてくれます。これを使ってテストの自動化を行うといったことをklabのセッションでやっていたようです(セッションは見ていないですが、公開されているスライドはとても有益でした)
Android向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステム

CreateGPUProgramの詳細が表示されるようになった

※Unity2019.3から対応

f:id:esakun:20190907214413p:plain:w450 ShaderVariantが切り替わる際の詳細が表示されるようになりました。

Profilerに任意のデータを埋め込めるFrameMetaData

※Unity2019.1から対応

Profilerに任意のデータを埋め込めるようになりました。

黒河さんのTweetで紹介されていました。

公式リファレンス

OnDemandRendering.renderFrameIntervalの追加

※Unity2019.3から対応

f:id:esakun:20190907214803p:plain:w450 描画処理のみスキップさせることができるようになりました。

OnDemandRendering.renderFrameInterval = 1;

例えば上のようにOnDemandRendering.renderFrameIntervalに1を代入すると、1フレームずつスキップされます。ターゲットフレームが60だった場合30FPSになるようなイメージです。2を代入したら15FPS。

元に戻したいときは0を代入します。


画面更新が不要な場合の処理負荷軽減をさせることができますし、描画だけを止めたい時に1行書くだけで実装できるのはとても楽です。

少し余談

OnDemandRendering.renderFrameIntervalはUnity2019.3から対応とのことですが、PlayerLoopをカスタマイズすればUnity2018でも対応は可能です。ショートカット的なAPIが追加されたということになります。

MeshAPI V2

NativeContainerを利用した動的メッシュ生成APIの追加が予定されているとのことです。これにより、GCAllocしない、また高速化が期待できます。実装タイミングはUnity2020辺りの予定らしいです。

最後に

今回パフォーマンス編としましたが、LWRP、DOTSについては外しています。DOTSについては別記事で執筆予定です。
聞き漏らした内容もあると思うので資料公開された際には、誤記がないかチェックしようと思います。また、早くUnity2019.3が安定化してもらいたいと思いました。