Unity+スマホで3Dゲーム開発最適化するための考え方

510ec964f5d26c2724c883fd7b671e3d?s=47 Cygames
January 14, 2016

 Unity+スマホで3Dゲーム開発最適化するための考え方

2015/11/15 Cygames Tech Fes

510ec964f5d26c2724c883fd7b671e3d?s=128

Cygames

January 14, 2016
Tweet

Transcript

  1. Unity+スマホで3Dゲーム開発/最適化 するための考え方 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  株式会社Cygames エンジニア

    金井 大
  2. 自己紹介 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 金井 大

    • 技術研究チーム所属のエンジニアです • VR、ゲームエンジン、グラフィックスとかの研究 開発してます
  3. アジェンダ $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • Unity +

    スマホで3Dゲーム開発/最適化する ための考え方を、以下で紹介します – 開発の指針 – 構成およびスペックの一例 – 開発と最適化のためのTIPS – 指針と手法の答え合わせ
  4.  開発の指針 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  5. 大事なこと $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 端末の性能を把握する •

    コンテンツの要素を把握する – 適切な単位で区切り – コストを把握し – そのコストを最適化する • 要素を選択できるようにする
  6. UNITY HARDWARE STATISTICS $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  •

    出典:http://hwstats.unity3d.com/mobile/ • unity mobile stat で検索
  7. 詳細 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • Mali 400

    MP: 20.0% • Adreno 305: 12.5% • PowerVR SGX543: 10.9% • Apple A7: 8.5% • Adreno 330: 5.9% • Adreno 306: 5.4% • Apple A8: 4.7% • PowerVR SGX544: 4.1% • Adreno 320: 2.8% • Vivante GC1000: 2.3% • Videocore IV: 2.2% • Mali 450 MP: 2.1% • Mali T760: 2.1% • PowerVR SGX540: 1.6% • PowerVR SGX531: 1.5% • Adreno 203: 1.4% • PowerVR SGX535: 1.3% • Adreno 200: 1.2% • PowerVR SGX554: 1.0% • Adreno 225: 0.9% • Adreno 405: 0.8% • Mali T628: 0.7% • Apple A8X: 0.6% • PowerVR G62xx: 0.5% • Mali T624: 0.5% • Tegra 2: 0.5% • Intel HD BayTrail: 0.4% • Adreno 220: 0.4% • Vivante GC2000: 0.4% • BlueStacks ES2.0 Emu: 0.3% • Tegra 3: 0.3% • Mali 300: 0.3% • Mali T720: 0.3% • Mali T622: 0.2% • Adreno 205: 0.2% • PowerVR G64xx: 0.2% • Adreno 420: 0.2% • Adreno 430: 0.1% • Immersion.16: 0.1% • Adreno 418: 0.1% • Vivante GC7000: 0.1% • Vivante GC800: 0.1% • Something strange: 0.1% • Adreno 304: 0.0% • PowerVR SGX530: 0.0% • Vivante GC4000: 0.0% • Android ES Emulator (GeForce): 0.0% • Tegra 4: 0.0% • Mali T604: 0.0% • Android ES Emulator (Radeon): 0.0%
  8. 3DMARK $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 出典:http://www.futuremark.com/hardware/mobile/ •

    3DMARK mobile results で検索
  9. 3DMARK $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 拡大

  10. どうしてこうなった $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • キャリア •

    チップセット • CPU – コア数 – クロック • GPU • メモリ
  11. PCゲームのグラフィックス設定 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 出典: http://doope.jp/media/15q1/img2826_01.j

    pg
  12. $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • どこまでユーザーに選択させるか?

  13. スマホでの現実解は? $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • ある程度は大まかに制御したい –

    エフェクト ON/OFF – 効果音 ON/OFF – FPS – スペックの抽象化
  14. $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 「スペックの抽象化」ってなんやねん

  15. 例えばシェーダーを例に $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • Vertex shader

    – カラーアニメーション – UVアニメーション – アウトラインメッシュの法線方向への拡大 – セルルック • Fragment shader – イメージエフェクト – スキンシェーダー – ノーマルマップ – セルルック
  16. アプリケーションでの抽象化 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • Vertex shader

    – カラーアニメーション – UVアニメーション – アウトラインメッシュ – セルルック • Fragment shader – イメージエフェクト – スキンシェーダー – ノーマルマップ – セルルック 低スペック 高スペック 使わない
  17. 端末に落とし込む $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • Vertex shader

    – カラーアニメーション – UVアニメーション – アウトラインメッシュ – セルルック • Fragment shader – イメージエフェクト – スキンシェーダー – ノーマルマップ – セルルック 低スペック 高スペック 使わない iPhone5s iPhone6 iPhone6s Galaxy  S5 Galaxy  S6
  18. 大事なこと $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 端末の性能を把握する •

    コンテンツの要素を把握する – 適切な単位で区切り – コストを把握し – そのコストを最適化する • 要素を選択できるようにする
  19.  構成およびスペックの一例 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  20. 目標 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 60fpsをキープしたい •

    キャラクターを5体表示 • 絵力 – フェイシャル – モーションキャプチャー – 他と差別された強い絵力が欲しい! • タイトなスケジュールに負けない
  21. より現実的なゴール $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 低スペック端末では –

    幅広く動作するようクオリティぎりぎりまでスペック を落としつつ60fpsをキープ • 高スペック端末では – 高性能端末で高品質な画面を提供しつつ60fpsを キープ
  22. キャラクター $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • スペック –

    テクスチャ • ETC1(αチャンネルなし)/PVR • Mipmapなし(データサイズ縮小のため – ウェイト • 基本は2ボーン – 3ボーンをPlayerSettingで2にするとメッシュが崩れることがあ る
  23. キャラクター $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • フェイシャル –

    ボーン制御 – Animatorで眼球、リップの動きを用意し、外部から 制御 – 眼球の追従先をプログラム制御 • アウトライン – アウトラインメッシュ – 頂点カラーでの調整 – リムライト、セルルックは…? • 造形が良ければアウトラインでも
  24. キャラクター $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • クロス –

    独自実装 – それなりに重いので、まずはC#でチューン • 計算部分のみなら22行程 – マルチスレッド化できるようにデータ局所化 – あとはネイティブプラグイン化すれば…
  25. 背景 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • テクスチャ –

    基本はETC1(αチャンネルなし)/PVR – Mipmapあり – UVアニメーション用に3MB程度を確保 • 画面キャプチャ – ImageEffectで作成した中間バッファを流用 – 1フレーム遅れた絵になるが低コスト
  26. その他 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • ライティング –

    基本的にはライティングしない – アンビエント – 板を1軸回転してカメラに向けてボリュームライトっぽく • シャドウ – リアルタイムシャドウは断念 – 板ポリの安いやつ。Diffuseに焼く。 • ないと立体感なくなります • パーティクル – 一定数まとまったメッシュを用意 – パーティクルとして降らせる – Vertex shaderで動きをつける
  27. Image Effect $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • ImageEffect

    – DOF(被写界深度 – Bloom – カラーコレクトはオミット • Unityのシェーダーをベースに – 1カメラで実現できるようカスタマイズ – ついでに高速化
  28. Directシーン $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • キャラクターや背景の任意組み合わせを確認でき る専用シーン

    • デザイナー/プランナーの作業、確認が主用途 • 各種アセットのデータ形式に対応 – 通常アセット – アセットバンドル(サーバー上 – アセットバンドル(ローカルPCにつくったやつ • 端末でも動作可能 – アプリ本体を経由しないので、単体テストやコスト計測 にも使える
  29.  開発と最適化のTIPS $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  30.  計測 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  31. Unity Profiler $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE 

  32. Statistics $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE 

  33. FrameDebugger $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • DrawCallを確認可能 –

    Unity5から こ の へ ん が 描 画 リ ク エ ス ト
  34. GPU Profiler $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 描画系の追跡はUnity

    Profilerでは限界がある – オーバーヘッド – GPUのプロファイルに難アリ • チップセットと対になったGPU Profilerを使う – iOS -> instruments / OpenGL ES Frame Debugger – Adreno -> Adreno Profiler – Tegra -> PerfHUD ES • 端末や要素の性能を把握できる
  35. 例:Adreno Profiler $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE 

  36. Adreno Profiler $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • プロファイルした情報を保存することが可能

    – チューニング前後の比較に • 頂点データ/テクスチャの保存 • シェーダーの可視化と変更 • Etc…
  37. Adreno Profiler $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • FrameDebuggerと同じくDrawCallが目視で

    きる
  38. Adreno Profiler $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • フレームバッファ、テクスチャのキャプチャ

    • シェーダー修正
  39. Adreno Profiler $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • FPSやGPU使用率などをグラフ化

  40.  描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  41. 描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • おおざっぱに以下のように考える –

    vertex負荷 = (描画リクエストされた頂点数) x (vertex shaderの命令数) – fragment負荷 = (描画されたピクセル数) x (fragment shaderの命令数) – 厳密にはパイプライン次第だと思う • 各ベンダー/各世代のチップ考慮するのは大変なので
  42. 描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 出典: http://climserv.ipsl.polytechnique.fr/documentation/idl_he

    lp/images/shader_detail.gif
  43. 描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 例:球(4000頂点)を(1/1)と(1/4)で描画し た時の比較

    – vertex負荷は同じ – fragment負荷は約1/16になる
  44. 描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • vertex負荷の制御はデリケート –

    描画対象となる頂点数を減らしたい – 何らかで頂点数を削れば良いのだが… • データ削減するとシルエット崩れや作業コストが懸念 • カリング精度を上げるにはCPU/GPU負荷が懸念 • fragment負荷は比較的制御しやすい – 描画面積とシェーダーで制御できる – カメラワークには注意
  45. 描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • vertexは最初から低めに抑さえる –

    特に低スペック端末を考えると低めにせざるを得 ない – 最低限のLODデータを用意する • fragment負荷を制御できる手段を用意する – ImageEffectをOn/Offする – 画面解像度を制御する – Meshのfragmentシェーダーを軽量版に切り替える
  46.  描画負荷軽減のポリシー $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  47.  描画順の制御 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  48. 描画順の制御 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 前提として「描画順」と「ZTest」を理解する –

    ZTestが有効な場合、隠れたfragmentは描画されない • 1がZ値的に手前にある時、1を描いてから2を描 くと、一部は描画されない 2 1
  49. 描画順の制御 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 極端にすると。 •

    1を描画してから2を描くと、2は殆ど描画されな い 2 1
  50. 隠れているのがポイント $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • アウトラインメッシュの描画が無駄になるので •

    こういう順番にしたい
  51. 描画順の制御 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 不透明は(基本的には)手前から描く –

    隠れた個所はfragmentシェーダーが走らない – 基本的にUnity側が手前からソートしてくれてる
  52. 描画順の制御 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • なんだけど –

    原点位置を基準にソーティングする – 意図した結果になるとは限らない – こういう時は床を最後にしたいが原点基準だと。。。
  53. 描画順の制御 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • Unityで描画順を制御する手段 –

    Camera.depth – MeshRenderer.sortingLayerName – MeshRenderer.sortingOrder – Material.renderQueue
  54. 描画順の制御 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 優先としては以下になる Camera.depth

    sortingLayerName =“default” sortingOrder =0 renderQueue=2000 renderQueue=2010 renderQueue=3000 sortingOrder =100 renderQueue=2000 renderQueue=2010 renderQueue=3000 sortingLayerName =“after” sortingOrder =10 renderQueue=2000 renderQueue=2010 renderQueue=3000 sortingOrder =200 renderQueue=2000 renderQueue=2010 renderQueue=3000
  55. Camera.depth $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • CameraはCullingMask設定が必要になるなど、 色々面倒

    – ImageEffect使用時は注意! • Camera.clearFlags=Depthだとclearが劇重 • GPU20%程度の消費することも
  56. MeshRenderer.sortingLayerName $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • sortingLayerNameは以下で追加可能 –

    Layers -> Sorting Layers • 記載の順番に処理される
  57. MeshRenderer.sortingOrder $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 同じsortingLayerNameでの描画順 •

    sortingLayerNameと合わせて運用を考える
  58. Material.renderQueue $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • マテリアル単位で描画順を制御する •

    Material.renderQueueはシェーダーからも設定可能 – Tags {"Queue"="Geometry-1" "RenderType"="Opaque"} • Queueは文字列に見えるけど実際は数値 – Background = 1000 – Geometry = 2000 – AlphaTest = 2450 – Transparent = 3000 – Overlay = 4000 • なので、前述の例は「1999」になる
  59. こんな事も $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 「髪の毛より手前にある眉」

  60. 髪の毛より手前にある眉 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 髪の毛に隠れてしまう眉毛を何とかして手前 に出したい

    – ZTest / ZWriteをOffにして対処 – ZTestしないので、「必ず」最前面に眉が描かれる (髪の上に描かれる) – ZWriteしないので、他のオブジェクトにZ値干渉し ない
  61. 髪の毛より手前にある眉 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 弊害として、他キャラの眉毛が貫通してくる可 能性がある

    – 描画順を制御して奥から描く • キャラA頭 • キャラA眉 • キャラB頭 • キャラB眉 • …
  62. 髪の毛より手前にある眉 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 問題はいくつか残る –

    頭と眉の形状によっては、自キャラの眉が貫通して くる • カメラワークでの回避 – 無駄な描画が発生する • 我慢する
  63.  SetPassとDrawCall $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  64. DrawCall $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • まずDrawCall –

    GPUへ描画リクエストする、ということ – 固有のマテリアルを描画リクエストすると 1DrawCall消費する – Unity5からStatisticsより消失しました
  65. $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 「固有のマテリアルを描画リクエストするとDrawCall 消費する」ってなんやねん •

    「固有のマテリアル」ってなんやねん
  66. DrawCall $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 固有のマテリアルとは –

    UnityEngine.Materialのメンバがユニークであるこ と – 例えば • Colorが異なる • Textureが異なる • Shaderが異なる • Etc… – 他と異なるメンバがあれば、それは固有である
  67. DrawCall $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • BOX全体にマテリアルA →

    DrawCall=1 • BOX各面にマテリアルABC → DrawCall=3 A A B C
  68. DrawCall $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • (BOX全体にマテリアルA)x2 →

    DrawCall=2 • (BOX各面にマテリアルABC)x2 → DrawCall=6 A A B C A A B C
  69. DrawCallとバッチ処理 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 同じマテリアルだったら最適化できそう •

    そこでバッチ処理 • 同じマテリアルをもつドローコールを統合する
  70. DrawCallとバッチ処理 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • (BOX全体にマテリアルA)x2 →

    DrawCall=1 A A
  71. DrawCallとバッチ処理 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • (BOX各面にマテリアルABC)x2 →DrawCall

    数は描画順に依存する(後述) A B C A B C
  72. DrawCallとバッチ処理 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • バッチ処理は2種類ある •

    StaticBatch – 移動しない同一マテリアルを持つメッシュをマーキングし、 事前にバッチ用のデータをしこむ – 統合の効果が高いが、移動したりマテリアル操作するメッ シュには適応できない • DynamicBatch – 前後のドローコールが同一マテリアルをもつ場合、ランタイ ム時に統合する – ランタイムに行うのでCPUコストがそこそこある – StaticBatchより効果が低い(頂点数等の制限数がある) • http://docs.unity3d.com/ja/current/Manual/DrawCallBatchin g.html
  73. DynamicBatch $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • DynamicBatchの注意点 –

    前後のドローコールが同一マテリアルを持たないと統 合しない – 描画順によっては統合できない! – 例えば描画順が以下だと統合されない • BOX(マテリアルA • BOX(マテリアルB • BOX(マテリアルC • BOX(マテリアルA • BOX(マテリアルB • BOX(マテリアルC • DrawCall=6になる
  74. DynamicBatch $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 描画順が以下であれば統合される –

    BOX(マテリアルA – BOX(マテリアルA – BOX(マテリアルB – BOX(マテリアルB – BOX(マテリアルC – BOX(マテリアルC – DrawCall=3になる • 描画順は前述のsortingOrderで制御可能
  75. DrawCall $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • DrawCallを減らすのであれば、描画時に固有 マテリアルが連続するよう、ルールを決めてお

    く – Batch処理を利用する – sortingOrder等で描画順を制御する – そもそも固有マテリアルを減らす • テクスチャを共有化する • シェーダーを共有化する • 変更するパラメーターを限定する • Etc…
  76. SetPass $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • SetPassとは –

    よりパフォーマンスの指針となる数値 – DrawCall時に前回使用したマテリアルから変更が あった場合、1SetPass消費する
  77. SetPassとDrawCall $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 【Unity】Unity Performance

    Casual Talk 「ド ローコール伝説の終わり」 レポート – http://qiita.com/baba_s/items/5260807ced7fc3c02ca 6
  78. SetPassとDrawCall $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • (BOX全体にマテリアルA)x2 →

    SetPass=1 • バッチに依存せず、SetPassは1になる A A
  79. SetPassとDrawCall $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • (BOX各面にマテリアルABC)x2 →

    SetPassは描 画順に依存する • SetPassを減らすにはDrawCallと同じく描画順を 意識する • DrawCallと同じノウハウが利用できる A B C A B C
  80.  Depth Texture $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  81. Depth Texture $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • ImageEffectの被写界深度はZ値を参照してボカ

    シ処理を行う • Z値を参照するには、DepthTextureが必要 – Camera.depthTextureMode = DepthTextureMode.Depth; • 注意点 – DepthTextureはRenderTargetへ描画を行うことで 生成されてる – DepthTextureへポリゴンを描いている、ということ – 単純に描画頂点数が二倍になる
  82. Depth Texture $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • DepthTextureへの描画時に利用されるシェー

    ダーは? – シェーダー中のTagsを参照してます • http://docs.unity3d.com/ja/current/Manual/SL- ShaderReplacement.html – UnityにLightModeというタグが用意されており、以 下タグを持つSubShaderに置き換わる • Tags{ "LightMode" = "ShadowCaster" } – Unity4 -> 5で変更された箇所なので注意
  83. Depth Texture $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • ShadowCasterシェーダーを実装する理由

    – アウトライン+DOF時に必要となる事がある – キャラクターはアウトライン分微妙にサイズが大き くなる • ので、DepthBufferに書き込む大きさを調整する – やらないとアウトラインがボケてしまう
  84.  Multi threaded Rendering $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  85. Multi threaded Rendering $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  •

    CPUがGPUを待つケースが減り、FPSの上昇が 期待できる • (空いてるCPUコア数が少ないと意味はない)
  86. Multi threaded Rendering $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  •

    なのですが。。。 – UnityのMultiThreaded Renderingに関する資料は 少ない – マルチスレッド関係は不具合出やすい個所なので 注意しましょう。 • Multithreaded + DynamicBatchでハングする事例あり • Unity5.0.2p3で発生
  87.  指針と手法の答え合わせ $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE

  88. 大事なこと $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 端末の性能を把握する •

    コンテンツの要素を把握する – 適切な単位で区切り – コストを把握し – そのコストを最適化する • 要素を選択できるようにする
  89. 端末の性能を把握する $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 実際に計測すること •

    Profiler – Unity Profiler – Frame Debugger – GPU Profiler • 各種サイト – 3DMARK – Unity Hardware Statistics
  90. 要素を適切な単位で区切る $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • ゲーム的かつ技術的な視点で区切る –

    キャラクタ/背景/エフェクト – 頂点数/テクスチャ/ボーン数 – シェーダー – ImageEffect – CPU/GPU
  91. コストを把握 $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 実際に計測すること •

    Profiler – Unity Profiler – Drame Debugger – GPU Profiler • CPU/GPUどちらがネックなのか • GPUネックならこれが参考になります • Computer Graphics Gems JP 2015 • http://www.borndigital.co.jp/book/5498.html# • 2.5.4 パイプラインのボトルネック解析
  92. コストを最適化する $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 定期的に監視すること –

    できるだけ早いタイミングから – 想定された端末でのチェック – 機能が入ると知らない間にコスト上がる • 配分を決めること • FPS/SetPassといった性能指針を
  93. 要素を選択する $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • What if

    – ◦◦したらどうなるだろう • キャラクタを増やすor減らす • ImageEffectをOn/Offする • シェーダーを切り替える • 選択を容易にする機能を実装する • ゲームと独立した場所があるとベスト
  94. おしまいです $POGJEFOUJBM $PQZSJHIU ˜$ZHBNFT *OD "MM3JHIUT3FTFSWFE  • 時間があればDEMO