CommandBufferのGPUコスト

今回の主な話題：CommandBufferのGPUコスト、Unityによって出力されたOBBファイルをどうやってロードしますか、LODの最適化順序、シーンの静的マージでLODと共存する方法、単一のRendererのTexture Mipmapレベルを制御する方法。

---
###レンダリング
Q1: 後処理ソリューション事前調査の実行中に、PostProcessV2で使用されるCommandBuffer方案は、V1のGraphicsインターフェイスを使う方案より多くのGPUコストを必要とするようであることが発見されました。
テストプロジェクトはこちら：[CBTest.unitypackage](https://uwa-public.oss-cn-beijing.aliyuncs.com/answer/attachment/public/103497/1552985933141.unitypackage)

実機テスト結果：
Redmi 2A（ローエンドモデル）で、Graphics.Blitを使用した後処理はフレームレートにほとんど影響を与えませんが、CommandBufferをオンにすると、フレームレートはすぐに60から40に引き下げられます。
Profilerの後、CommandBuffer.BlitのコストはGraphic.Blitより低いです（前者の場合は0.0x ms、後者の場合は1.x ms）が、CommandBufferを挿入したDevice.Presentは大幅に高くなります。
ハイエンドモデルに変えて100回の後処理を行っても、結論は同じです。2つの方案は同じShaderを使用し、簡単な色計算であり、Shaderの影響を排除できるはずです。

CommandBufferはGPUコストをより多く消費しますか？もしそうなら、この部分のコストはどこにありますか？コストが高い場合、柔軟性以外にCommandBufferの利点は何ですか？
>大体見ましたが、私の分析は以下になります。
これは、cmdBuffer.Blit(BuiltinRenderTextureType.CurrentActive, mainTexId)；を使用して公式バージョンにコピーしましたから。元のやり方はcmdBuffer.SetGlobalTexture(mainTexId,BuiltinRenderTextureType.CurrentActive);であります。

問題主からの補充：
ここに別の質問があります。私は最初にSetGlobalTextureを使用しようとしました。

```ruby:
cmdBuffer.SetGlobalTexture(mainTexId, BuiltinRenderTextureType.CameraTarget); 
cmdBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); 
cmdBuffer.DrawMesh(FullscreenTriangle, Matrix4x4.identity, BriMaterial);
```

Frame Debuggerが見たShaderに入力されたのはDrawMeshに三角形を描いた画像であります。これでBackBufferから画像を取得し、同時に書き込む場合、時間順序の問題があると推測できます。PostProcessV2にDrawMeshが使用されたから、入力されたsourceが生成するのはBuiltinRenderTextureType.CurrentActiveではなく、RenderTextureであります。
>具体的なコードはテストしていませんが、２つのアイデアを提供できます。1つはCamera.renderTarget.colorBufferを使用することです。必ずしもCustomRenderTextureである必要はなく、デフォルトのカメラも取得できます（Unity 2019）。もう1つは、TAAを使用することです。前のフレームのデータをholdします。

---
###OBB
Q2: Unityの公式チュートリアルが推奨しているAssetStoreのGoogle Play OBB Downloaderプラグインのコア関数はWWW.LoadFromCacheOrDownloadです。
Unityが2017バージョンにアップグレードした後、この関数はOBBパッケージをロードすれば、解凍失敗になります。
プラグインは4年間更新されていませんが、探したらこの問題が発生している人がいることがわかりました。 誰かがこの問題を解決しましたか？

①
>
UnityがAPK + OBBを直接出力しても問題ありません。Unityエクスポートプロジェクト+ OBBの場合、OBB検証が失敗するため、一部のプロジェクトはOBBを使用できない場合があります。UnityエクスポートプロジェクトAndroidManifest.xmlに１つのmeta-dataがあります。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/b8410376-e608-adcb-53b3-42e09b74eab7.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/88d3b3d4-47b5-0b0b-ac1c-b39eb7df6c13.png)
このvalueは、OBB解凍後の検証ファイルに対応したら大丈夫です。

②
>
Androidの権限Bugに遭った経験があります、SDカードの読み取りと書き込みの権限がなく、OBBも使用されています。一部のモデルではエラーが発生し、スマホを再起動すると正常に起動できます。

---
###LOD
Q3: LODの最適化順序について。例えば、シーン、キャラクター、モンスター、NPCの優先順位は妥当ですか？
>面のレンダリング から言うと、通常、シーン部分がレンダリングする面の数は比較的に高いで、LODする必要があります。次にキャラクター部分も考えられます。DrawCallとOverdrawから言うと、LODにパーティクルシステムを追加することをお勧めします。これは、特殊効果でアクティブ化されたパーティクルシステム数、放出パーティクル数、およびパーティクル面積を高、中、低レベルのように制御するためです。

---
###LOD
Q4: シーンの静的合併はLODとどのように共存できますか？静的合併を禁止し、Mesh Bakerを使用してメッシュとLODの結合を手動で合併しますか？
>Unityに組み込んだLODGroupとStatic Batchingは同時に使用できますが、Lightmapをオンにした後でいくつの問題を処理する必要があるかもしれません。

このQAで討論した問題を参考できます、https://answer.uwa4d.com/question/5ad836acbdcd031091afdb80。 （中国語注意）

---
###Mipmap
Q5: テクスチャのMipmapをオンにすると、少しぼやけた感じになります。単一のRendererのTexture Mipmapレベルをどうやってコントロールできますか？
>単一のテクスチャのMipmap選択を制御することは確かに可能です。GPUがテクスチャをサンプリングするとき、Mipmapレベルの選択は、Mipmap Biasを介して変更できます。このパラメーターの具体的な意味と使用上の制限については、https://docs.unity3d.com/ScriptReference/Texture-mipMapBias.html を参照してください。ただし、この値を変更すると、GPUのパフォーマンスコストが増加する可能性があるため、注意を払う必要があります。

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

UWA公式サイト：https://jp.uwa4d.com
UWA公式ブログ：https://blog.jp.uwa4d.com