Upgrade to Pro — share decks privately, control downloads, hide ads and more …

「IDOLY PRIDE」における描画最適化術 / IDOLY PRIDE Graphics Optimization

「IDOLY PRIDE」における描画最適化術 / IDOLY PRIDE Graphics Optimization

CA.Unity#2で発表した資料になります。
ScriptableRendererPipelineと、描画APIを利用したパフォーマンスチューニングについて紹介します。

8192a3d22a844b926f2e1bd7aef5fb25?s=128

QualiArts

July 13, 2021
Tweet

Transcript

  1. 「IDOLY PRIDE」に おける描画最適化術 株式会社QualiArts 渡邉俊光

  2. 自己紹介 • 2012年CyberAgent新卒入社 • オルタナティブガールズ等の開発を経て 株式会社QualiArtsのTA室で「IDOLY PRIDE」(以下アイプラ)の 3D実装全般を担当

  3. アイプラとは? 2021年6月リリース、アイドルマネジメントRPG

  4. アジェンダ • 実行環境 • ScriptableRenderPipeline(SRPBatch) • 描画API ◦ レンズフレア(DrawProcedural) ◦

    ボリュームライト(DrawMeshInstancedProcedural) ◦ 観客(DrawMeshInstancedIndirect)
  5. 実行環境

  6. 実行環境 • Unity2020.3.4f1 • UniversalRenderPipeline 10.5.0 • GPU Lightmapper •

    HDR+Linear Rendering • 対象プラットフォーム ◦ Android→Vulkan(OpenGLES3.1も一応動作…) ◦ iOS→Metal GPU family 3以降(Apple A9) ◦ 5年前のハイエンドがギリギリ動く目安 Unity新機能たくさん かなり攻めてる
  7. None
  8. ScriptableRenderPipeline

  9. UniversalRenderPipeline(SRP) • ScriptableRenderPipelineを拡張したUnityの新 しい描画システム • HDRPと違い、様々な端末で動作するように チューニングされている • RendererFeatureを作成することで簡単に CommandBufferを追加できる

    Legacyではカメラに追加だったので非常に面倒 +SceneViewの扱いが面倒だった • ポストエフェクトはPostProcessPassを複製して 書き換えすることで処理効率化
  10. ShaderGraph • ShaderGraph 10.5.0 • UniversalTargetを追加して自前の 処理を挿入 • バージョンが上がるたびに仕様が変 わっていて泣く

    • SRPBatchやUnity標準の最適化が入 るのでとても便利
  11. SRPBatch • ScriptableRenderPipelineのメイン機能?とも言える新しいバッチシステム • Metal又はVulkanに対応 • SetPassを最小限にしてDrawCallの発行効率を最適化高速化→CPU高速化 • アイプラではキャラクター、背景全てでSRPBatch対応 •

    適用には様々な条件や罠がある • 割と最近まで動作が不安定だった • Unity公式→ SRP Batcher:レンダリングをスピードアップ
  12. SetPassCall 283 → 155 !!

  13. 描画API

  14. 軽量化するには? • C#が重すぎる!!(100個くらいのオブジェクトで割とアウト) • C# JobSystem (Burst) = 神 •

    ComputeShader = 超神 • ComputeBufferを描画APIと組み合わせる(SSBO対応必須) Compute >>>…>>> Burst >>>>>...>>>>>C# 体感これくらい
  15. レンズフレア(DrawProcedural) • アイプラではProFlareを使用 • 描画、更新処理はほぼ全て書き換え • DrawProceduralで描画 • 9ms →

    1.6ms(ベンチマークシーン) C# 座標系、画面内判定 Burst 値更新しつつ ComputeBufferに整形 ComputeShader DepthTextureと当たり判定
  16. DrawProcedural • https://docs.unity3d.com/ja/current/ScriptReference/Rendering.Comm andBuffer.DrawProcedural.html • メッシュ不要 • 頂点のつなぎ方と数だけで大抵の描画ができるAPI • GraphicsBufferでIndexのバッファを送ることで自由なつなぎ方も出来る

    void DrawProcedural (GraphicsBuffer indexBuffer, Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, int indexCount, int instanceCount, MaterialPropertyBlock properties);
  17. ボリュームライト(DrawMeshInstancedProcedural) • ボリュームライトには VolumetricLightBeam(VLB)を使用 • 描画、更新処理はほぼ全て書き換え • DrawMeshInstancedProceduralで描画 C# VLB値更新

    Burst AABBカリング
  18. DrawMeshInstancedProcedural • https://docs.unity3d.com/ja/current/ScriptReference/Rendering.Comm andBuffer.DrawMeshInstancedProcedural.html • メッシュを複製して描画 • 細かい設定は出来ないがMaterialPropertyBlockでComputeBufferを入れて おくことでInstancing毎に色を変更できる void

    DrawMeshInstancedProcedural (Mesh mesh, int submeshIndex, Material material, int shaderPass, int count, MaterialPropertyBlock properties);
  19. 観客(DrawMeshInstancedIndirect) • 観客は動員人数を自在に変動可能(Max32768) • 座席データに優先度がある • カメラに近い観客は体も描画 • DrawMeshInstancedIndirectで描画 C#

    座席データから ComputeBuffer生成 ComputeShader 境界球カリング ModelMatrix更新 数値更新
  20. DrawMeshInstancedIndirect • https://docs.unity3d.com/ja/current/ScriptReference/Rendering.Comm andBuffer.DrawMeshInstancedIndirect.html • パラメータにIndirectBufferを使用してメッシュを描画 • IndirectBufferにInstancing数等を入れておくことでCPU側での指定が不要 • ComputeShaderで全て計算できる!

    void DrawMeshInstancedIndirect (Mesh mesh, int submeshIndex, Material material, int shaderPass, ComputeBuffer bufferWithArgs, int argsOffset, MaterialPropertyBlock properties);
  21. まとめ • Vulkan世代をベースにすることで様々な最適化が可能になり今まで出来な かった表現が可能となる • Burst対応をすることでCPU問題はかなり解決できる (Burst出来ない箇所が重すぎるのが課題…DOTS? ) • ComputeShaderは爆速だがAndroidでは過信しすぎないように

    →iPhoneに比べてComputeの実行速度はそこまで進化していない罠 • Androidローエンド端末問題はある…