Unityのパフォーマンス最適化部分

[Unity スキル] Unity の最適化テクノロジー_Mom は、女の子は独立して自立するべきだと言います。 blog-CSDN blog_Unity 最適化モデル

Unity 最適化スキル (中) - Zhihu



Unity 最適化のヒント (パート 2) - Zhihu

1. 最適化の方向性

1. 頂点の最適化

     (1)ジオメトリの最適化: モデル内の三角形の数を可能な限り減らし、頂点を可能な限り再利用します。

    (2) LOD(Level of Detail)技術の活用

     UnityLOD 最適化技術の詳細説明_丶Bo Liang のブログ - CSDN ブログ_lod 最適化

    (3) オクルージョンカリング技術の活用

2. ピクセルの最適化

(1) ピクセル最適化の焦点は、オーバードローを減らすことです。オーバードローとは、ピクセルが複数回描画されることを指します。重要なのは、描画順序を制御することです。

透明なオブジェクトを描くときは、前から後ろに描くようにする必要があります。前から後ろに描画するとオーバードローを減らすことができるのは、深さのチェックのためです。

Unity では、シェーダーの「ジオメトリ」キューに設定されているオブジェクトは常に前から後ろに描画されますが、他の固定キュー (「透明」、「オーバーラ」など) のオブジェクトは後ろから前に描画されます。 . . たとえば、skyboxの場合、ほぼすべてのピクセルをカバーしており、常にすべての背後にあることがわかっているため、そのキューを "Geometry+1" に設定できます

(2) GUI 描画と 3D シーン描画を別のカメラに引き継ぐことができ、3D シーンを担当するカメラの視野角範囲は可能な限り GUI と重ならないようにします。

(3) リアルタイム ライティングを減らす: シーンに 3 つのピクセル単位の点光源が含まれており、ピクセル単位のシェーダーを使用する場合、ドロー コールが 3 倍になり、オーバードローも増加する可能性があります。ピクセルごとの光源、これらの光源によって照らされたオブジェクトが再度レンダリングされます。さらに悪いことに、動的バッチ処理も動的バッチ処理も、そのようなピクセルごとのパスに対してバッチ処理できないことです。つまり、バッチ処理が中断されます。

(4) ライトマップを使用する

シーン内の照明情報を事前に照明テクスチャに保存しておけば、実行時にそのテクスチャに基づいて照明情報をサンプリングするだけで済みます。

3. CPUの最適化

描画呼び出しを減らす

        (1) バッチ処理:同じマテリアルを使用するオブジェクトの場合、それらの違いは頂点データの違いだけです。つまり、使用されるメッシュが異なります。これらの頂点データを結合し、一緒に GPU に送信してバッチ処理を完了できます。

        Unity が動的バッチ処理を実行するための条件は、オブジェクトが同じマテリアルを使用し、特定の条件を満たすことです。頂点は 900 を超えることはできず、xyz スケーリングは統一されている必要があります。ライトマップを使用するオブジェクトはバッチ処理されません。マルチパス シェーダバッチ処理を中断し、リアルタイムを受け入れます。シャドウ処理も行いません

        静的バッチ処理:「静的フラグ」をチェックし、「静的」の後ろにある三角形のドロップダウン ボックスをクリックします。このステップで実際に多くのことが設定されることがわかります。ここで必要なのは「静的バッチ処理」だけです。静的バッチ処理の前に同じメッシュを共有するオブジェクトがいくつかある場合 (たとえば、2 つの同一のボックス)、各オブジェクトはメッシュのコピーを持つことになります。つまり、1 つのメッシュが複数のメッシュになります。GPU に送信されると、欠点は次のとおりです。より多くのメモリを消費するということです。

 (2) テクスチャのマージ (Atlas):できるだけ多くの小さなテクスチャを 1 つの大きなテクスチャ (Atlas) にマージします。

4. 帯域幅の最適化

(1)テクスチャのサイズを縮小し、テクスチャの [Advance] パネルでパラメータを調整します。最適化に関連する主なオプションには、「Generate Mip Maps」、「Max Size」、「Format」などがあります。

「Generate Mip Maps」では、同じテクスチャに対してさまざまなサイズの小さなテクスチャが多数作成され、テクスチャ ピラミッドが形成されます。ゲームでは、オブジェクトからの距離に基づいて使用するテクスチャを動的に選択できるため、より多くのメモリを消費します。

「最大サイズ」はテクスチャの長さと幅を決定するもので、使用するテクスチャがこの最大値を超える場合、Unity はこの条件を満たすようにテクスチャを縮小します。

「フォーマット」は、テクスチャによって使用される圧縮モードを担当します。通常、この自動モードを選択するだけで、Unity がさまざまなプラットフォームに応じて適切な圧縮モードを選択します。

2. 細部の最適化

1. LOD、コードは必要な場合にのみ実行されます

        画面外のキャラクターは、アニメーションの更新、スキル効果、体力バーの不正行為などにはカウントされません。画面外のキャラクターは休眠状態であり、主人公のみが不正行為を行うことができます。

2.フレーム制限、負荷分散

プレーヤーモデルに基づいてフレームを制限する

3.アルゴリズム

コード自体に対するいくつかの操作。たとえば、物理操作の最適化、スペースと時間の交換、テーブル ルックアップの事前計算やその他の方法を使用した計算の高速化、頻繁なインデックス作成、FindGetComponentd およびさまざまな操作の削減などです。

4.ユニティインターフェース

GetComponent、AddComponent (GC も生成)、Find およびその他の操作はできるだけ使用しないようにしてください。

 OnGUI、FixedUpdate、Update などの空の関数にも gc オーバーヘッドが発生します。これは、C++ から C# レイヤーへの呼び出しにオーバーヘッドが発生するためです。

 MainCamera はトラバース操作であるため、カメラが多数ある場合は頻繁に呼び出さないでください。

位置と回転を同時に変更する場合は、SetPositionAndRotation()メソッドを使用して一度に設定します。

5.物理学

最適化の観点からは、レイヤー化によって衝突ペアを減らすことができます。MeshColliderの代わりに BoxCollider を使用するようにしてください。UI インターフェイスをクリックする必要のないコントロールには Raycaster を開かないでください。最も基本的な X 線検査を使用します。

6、IL2CPP & C++

UnityのコンパイルをIL2CPPに設定すると、C++版の実行効率が大幅に向上します。

7. アニメーション

Animator.Update または MeshSkinning.Udpate が Prifile で見つかった場合、オーバーヘッドが比較的大きく、アクションを最適化する必要がある可能性があることを示しています。

  

最適化:

(1) 最適化を開く

GameObject では、無効なノード ボーンをいくつか削除できます。カスタム ノードがある場合は、それらを最適化されていないリストにドラッグする必要があることに注意してください。  

   

(2) 圧縮:

KeyframeReduction をオンにすると、多くの不要なキーフレームが圧縮され、値が大きいほど圧縮率が高くなり、歪みが大きくなります。

(3) ボーンウェイト:

頂点はボーンの影響を受けるため、要求が厳しくない環境では 1 つのボーンで十分な場合があります。モデルごとに設定することも、リアルタイムでグローバルに変更することもできます。

  

(4)ベイクメッシュ:

同じ画面上に多数のモデルを表示する必要がある場合は、SkinnedMeshRenderer.BakeMesh を使用してアニメーションをモデルにベイク処理し、レンダリング中に結合できるようにすることができます (アニメーションは結合できません)。DC は大幅に削減され、スキニング計算が省略されますが、メモリが増加し、DynamicBatching の CPU オーバーヘッドが増加し、パフォーマンスが低下するという欠点があります。

(5) Animator を使用しない場合:

Animator のオーバーヘッドは Animaton よりも桁違いに高くなります。

(6) Invisible では設定 CullCompletely が更新されません

ただし、一部のメッセージも停止するため、アニメーションに依存している場合には問題が発生する可能性があることに注意してください。

(7) ボーン LOD、GPU スキニング (一部のデバイスや状況では遅くなります)、CS の代わりにボーンを使用するなど。

8、UI

UI も大きな出費であり、通常 30% ~ 50% を占めます。
UGUIは、NGUI の LastUpdate に似たProfile の Canvas.BuildBatch および Canvas.SendWillRenderCanvases のオーバーヘッドに対応します。UI の最適化に関する記事は数多くありますが、ここでは簡単にリストします。

 (1)、動的分離と静的分離:

UIが統合されるからです。NGUI はPanel に基づいて再構築され、UGUI は Canvas に基づいて再構築され、動的 UI がマージをトリガーして静的 UI がマージされるのを防ぎます。

 (2)、プリロード、常駐、即時リリース:

UI はタイプごとに分かれており、大きくてよく使用される UI は作成中にスタックするため、事前に読み込むことができます。主要都市から戦闘シーンまで、ピークメモリを確保しながら、ヒーローインターフェイス、ユニオンインターフェイスなどの永続メモリによりロード速度が向上し、実際の測定と最適化により、ロード速度が2倍以上に向上しました。使用頻度の低いその他のインターフェイスは小さなインターフェイスに分割され、すぐにロードされ、メモリを節約するために閉じるときにアンロードされます。UI ノードが多すぎると読み込みも遅くなることに注意してください。以前は 10 秒間読み込みをしていましたが、そのうちシリアル化された UI が時間の約半分を占めていました (テクスチャのプリロード テスト)。UI ノードの数が減れば、大きすぎて分解されてしまいます。

 (3)、アトラス

UI アトラスを合理的に分割し、パブリック アトラス (常駐) と非パブリック アトラスを区別します。サイズが大きすぎると、冗長なロードが発生しやすくなり、過剰なメモリ使用量が発生しやすくなり、メモリとビデオ メモリのスワップ オーバーヘッドが発生します。小さすぎるとメモリの断片化が容易に発生し、効率に影響を与える可能性があります。ルールは複雑です。

(4)、メモリプール

UI エイリアシングなどの頻繁に作成される UI は、作成時間とメモリの断片化を軽減するためにメモリ プールを使用します

 (5)、アクティブ/非アクティブ

アクティブ/非アクティブで UI インターフェイスを頻繁に切り替えることは、UI マージ操作をトリガーするため推奨されません。画面外に移動するか、レイヤーを設定することができます。ただし、画面外に移動してもマージされて描​​画されてしまうので、長時間表示しない場合は状況に応じてDeactiveを使用した方が良いでしょう。

 (6)、UITexture の代わりに UISprite: テクスチャはマージされません。

 (7)ヘルスバーの名前など、非表示の UI は移動しないと更新されません

 (8) レイアウト グループおよびキャンバス グループ コンポーネントの場合、親ノードを変更する子ノードは、getcompent を使用してレイアウト グループを検索します。これらは Unity の UGUI の 2 つの大きな落とし穴です。

 (9)拾う必要のないRaycastターゲットの電源が切れていないか確認してください

 (10) リソースのプリロード: たとえば、前に紹介した UI のプリロードでは、メモリが許せばすべてのリソースをメモリ プールと組み合わせてプリロードする必要があります。ゲーム内のすべての収益化ロジック、キャラクター、モンスター、小道具、UI がプリロードされ、一連のプール拡張およびリサイクル戦略が存在します。

 (11)、シェーダーのプリロード。

9、GC

GC は非常に高価なシステム コールであり、ほとんどの遅延の主な原因でもあり、完全に制御することはできません。したがって、頻繁な GC のトリガーを防ぐためにコード ヒープ メモリの過剰な割り当てを最小限に抑える必要があると同時に、読み込み中やパフォーマンスが重視されない場合には積極的に GC を実行することもできます。

(1) GC オーバーヘッドを削減するには、文字列の代わりに StringBuilder を使用します。リッチ テキストを使用して、Text コンポーネントの色を変更して Text コンポーネントの色を直接変更しないでください。

 (2)、クラスオブジェクトのメモリプール頻繁に作成および削除されるものはすべて使用する必要があります目的は 2 つあります。ロード、作成、解放の時間を短縮し、メモリの断片化を削減し、GC の頻度を削減します。

(3) Unityインターフェース:AddComponent、OnGUI、UIマージ頻度、デリゲートなど(一部のForeach、コルーチンなどUnity最適化済み)

(4) プラグインの GC 最適化: Behavior Tree や FMODStudio などの一部のプラグインのソース コードが、GC を削減するために変更されました。

3. GPUの最適化

(1). DrawCallの最適化には通常、マテリアル メッシュのマージが含まれるため、GPU 上に配置されます。1 つのメッシュを持ち、一度に 1 つのマテリアルを運ぶオブジェクトをレンダリングするには、描画呼び出しを使用します。DCを一度呼び出すとブラシが変化して製図板上にオブジェクトを描画していることが分かります。

(2)辺の数

シーン全体には 10 未満の DC が含まれており、アーティストまたはプラグインによって結合されて出力されます。静的マージではロード時間とメモリが増加し、動的マージではメモリとマージ CPU オーバーヘッドも増加します。

(3)、LOD

GPU の最適化は、モデル LOD 、ボーン LOD、パーティクル LOD、マテリアル LOD、テレイン LOD などを介して実行できる LOD を通じて行うこともできます。たとえば、構成が異なると、異なるエフェクトが有効になり、後処理が有効になります。

(4)、ブロッキング

オクルージョン カリング:名前が示すように、壁の後ろのオブジェクトなど、ブロックされていて見えない領域はレンダリングされません。オクルージョン カリングは CPU または GPU によって計算できます。

UI オクルージョン: たとえば、全画面 UI は背景を隠して電力を節約できます。

シーン分割:俯瞰で見ているので遮るものが少ないので、そのままシーン分割しています。

(5)、半透明

半透明性は多額のコストがかかるため、レンダリング パイプラインの最適化が損なわれますまた、アルファ チャネルを使用してテクスチャを圧縮することも困難です (特に IOS 上の PVR 形式は、アルファ ピクセル圧縮後に大きな損失が発生します。ETC、DDS、PVR など)フォーマットには 1 つのアルファ チャネルがあり、圧縮率は他の 3 チャネルと同じです)。

使用量を減らす/領域を減らす: 使用量をできるだけ少なくし、画面が占める領域を最小限に抑え、ピクセルの充填率を下げるために使用します。

(6)、粒子

画面のカバー領域を減らし、アルファの使用を避け、マテリアルとメッシュをマージします。LOD = モデルまたは距離に応じてパーティクル エミッターの数と効果を減らします。シーケンス フレーム: 一部のトップダウン ゲームでは特殊効果にシーケンス フレームを使用することもできます。効率が向上します。

(7)、その他

  • レンダリング設定: シャドウ、フォグ、アンチティース、垂直同期、異方性、マルチスレッド レンダリング、GPU 計算スケルトン、ボーンの影響を受ける頂点、ソフト パーティクルなど。各プロジェクトには異なる要件があります。
  • レンダリング解像度を下げる: PS のオーバーヘッドとメモリを減らすために Framebuff 解像度を下げますが、ぼやけてしまいます。Honor of Kings などの多くの主流ゲームは Android で解像度を下げています。
  • インテリジェントな動的調整: プレーヤーの構成とゲーム環境に応じてリアルタイムで構成を調整します。低構成の装備や戦闘用の低構成ではフレームが制限されます。高構成のプラグインや低オーバーヘッドのシナリオでは構成が動的に改善されます。そしてフレーム制限を増やします。より詳細な紹介が記載されたドキュメントがあります。
  • 後処理: Unity では、Graphics.Blit のパフォーマンスを見ることで後処理のオーバーヘッドを理解できます。後処理は一般にピクセルレベルの計算であり、モバイルデバイスの解像度は一般的にPCよりも高いため、使用する場合はより注意が必要です。
  • 多次元サブマテリアル材料は使用されません。

4. メモリの最適化

1. 圧縮テクスチャ ETC/PVR: テクスチャが最も多くのリソースを占有します。基本的に 3D テクスチャを圧縮し、2DUI テクスチャを部分的に圧縮します。Android では ETC 形式、IOS では pvr 形式を使用してみてください。非半透明の圧縮率は 1/8 です。これら 2 つの圧縮形式は DX の DDS に似ており、グラフィック カードによって直接レンダリングできるため、メモリが削減されるだけでなく、パッケージ サイズが削減され、読み込み速度も向上します (JPG およびその他の形式は圧縮率が高いですが、解凍する必要があります)レンダリング前に 32 ビット カラーに変換するため、追加のメモリ、ビデオ メモリ、および追加の解凍オーバーヘッドが必要になります)。次の点に注意する必要があります。

(1) 圧縮効果が良くない場合は、16 ビットカラーに減色することができます。

(2) ミップマップをオフにする: UI または俯瞰ゲームでミップマップが必要ない場合は、ミップマップをオフにしてサイズを 1/3 に減らすことができます。

(3) ETC を使用する場合、PVR 圧縮マップは 2 のべき乗である必要があります。レンダリング効率とビデオ メモリの断片化を考慮すると、マップの最大サイズは 1024 が推奨され、最小は 64、最大は 2048 を超えることはできません。 。

(4) Jiugong の対称テクスチャを使用: テクスチャの再利用率を向上させます。

(5) シェーダ: シェーダを使用してテクスチャ チャネルをマージし、グレースケール画像などを実現します。アルファ チャネルはアルファテストとハイライトを保存し、テクスチャの 1 つのチャネルはシャドウを保存し、別のチャネルは ao などを保存します。アルファ チャネルは、圧縮などを容易にするためにテクスチャの他のチャネルを保存します。これは、Xuanyuan Legend の作業時に大いに使用されました。

(6) アニメーションを圧縮してキーフレームを削減: 前に紹介しました

(7) タイムリーなアンインストール:シーンに出入りするとき、UI インターフェイスを開いたとき、その他のパフォーマンスに影響されないときに、リソースをアンロードし、 Resource.UnloadAsset を呼び出して参照リソースをクリーンアップして破棄し、 System.GC.Collect を呼び出します。前述したように、システム リソースをクリーンアップします。AssetBundle はロード時に生成され、アンロード時に破棄されます。これは比較的大きな落とし穴でもあります:)

(8) コード レベルでの不必要なヒープ メモリ割り当てを回避します。これは、静的コード分析を通じてチェックできます。これについては、別の記事で詳しく説明します。

(9)頻繁な新しいクラスを避ける: メモリ プールを使用します

(10) 文字列接続: 文字列の結合を減らす、StringBuilder を使用するなど。

(11) デリゲート: 内部リンク リストとボックス化およびボックス化解除操作のため、使用頻度が高いと GC が高くなります。

(12) ラムダ式の適切な使用: たとえば、Unity のパーティクル システムのバージョン 5.6 より前の GC が高かったのはこれが理由です。

(13) 一時変数や一時リストが頻繁に生成される場合は、グローバルリストを定義し、毎回このリストを計算に使用することをお勧めします。

(14) クラスはヒープ上に、構造体はスタック上に割り当てられることに注意してください。構造体が使用される場合もあります。

(15) メモリ リーク: Unity は参照カウントに基づいています。一般にメモリ リークは、保持されたまま解放できないリソースです。メモリ増加傾向は明らかであり、シーンを繰り返し切り替えるとメモリが増加します。この状況に備えて、各シナリオのリソース ログを出力する独自のツールを作成できます。XCode を使用してメモリを経時的に分析することもできます。

(16) テーブルデータ。通常、テーブルはアンロードされません。文字列を直接使用するのではなく、バイナリ逆シリアル化を使用し、複数のコピーをメモリにキャッシュしないことをお勧めします。テーブル データが非常に大きい場合は、使用後に削除することを検討してください。

(17) 冗長な頂点データ: UI マップメッシュは適用できないカラー、法線などをエクスポートするため、静的に結合するとメモリの増加につながります。

(18) アンチエイリアス/レンダーテクスチャ: アンチエイリアスをオンにするとメモリが増加し、高解像度にするとメモリが増加します。レンダーテクスチャは後処理で交互に使用でき、複数のコピーを作成する必要はありません。

(19) ゲームオブジェクトの数: 1w 未満 ノードブックが多すぎると、ロードと更新の速度が遅くなり、メモリの拡張も発生します。

4. フラッシュメモリ

具体的には、パッケージのサイズ、リソースの読み込み速度などに反映されます。フラッシュ メモリの最適化はメモリの最適化とほぼ同じですが、例外もあります。たとえば、jpg を使用すると、パッケージ サイズが削減され、CPU のメモリ消費量が増加します。圧縮はメモリと同じです。テクスチャ、アニメーション、ガイドテーブルなど

(1) コード ストリップ機能をモバイル プラットフォームでオンにして、コードによるメモリと容量の消費を削減できます。リフレクションを使用するクラスの場合、link.xml 構成を使用して問題を解決できます。コードストリップはUnityが提供する最適化機能で、コードの実行経路を事前に判定し、使われていない機能を削除します。

(2) 一部の SDK は非常に大きいため、サードパーティと交渉して重複ライブラリを減らすことができます。

(3) l2cpp には ARMv7 と ARM64 の 2 つのバージョンのコードが含まれるため、2 つのコード ボリュームが存在します。

(4) 動的ダウンロード: マイクロクライアントに似ています。ただし、プレイヤーデータを使用する可能性があるため、携帯電話ではお勧めできません。

(5)冗長リソース: パッケージをエクスポートする場合、プラグインまたは自作ツールを使用してリソースを分析します。

(6) テクスチャ メッシュの動的生成: 以前に使用された有名な物質など、いくつかの規則的なテクスチャとモデルは計算によって生成できます。また、前回のエンドゲームで地形を最適化するときに、地形の高さのみが保存され、残りの高さが保存され、GPU は地形情報に復元され、1/3 などに削減できます。

5. ネットワーク

1. パッケージ本体を縮小して圧縮します。バイナリに対して再利用とマージを実行してパッケージ本体を縮小し、プロトコル パッケージを圧縮します。

2. パケット結合: 特定の頻度でパケット結合操作を実行し、いくつかのパケットを結合して送信頻度を減らし、パケット ヘッダーを削減します。

6. 消費電力

1.CPG、GPU最適化、ネットワーク最適化、

2. フレーム制限: モバイル ゲームでは通常、フレームが 30 フレームに制限されます。

3. 画質とエフェクトを削減し、更新頻度と LOD を削減します。

おすすめ

転載: blog.csdn.net/qq_35647121/article/details/128864129