結果を得る

パーティクル システムとの共通トラブル領域をプロファイリングします。

Choose your operating system:

Windows

macOS

Linux

カスケードのコアシステム - GPU/ ゲームスレッド / レンダリング スレッド

カスケードは、UE4 のコアとなる 3 つのシステム全体に動的な負荷がかかる剛健なパーティクル システムを作成します。それはゲームスレッド、レンダリング スレッド、GPU です。

  • パーティクル シミュレーション時間 (Tick) はゲームスレッド上で計算されます。

  • パーティクル データの仕上げ (ジオメトリのパック、ドローコール) はレンダリング スレッドで計算されます。

  • パーティクルのビジュアル (シェーダーの複雑さ、オーバードロー) は GPU で計算されます。

これらのシステムすべてが互いに平行して計算を実行するため、どれか 1 つでも遅くなったシステムがあれば、レンダリング プロセス全体のボトルネックとなり、フレームレートが低下します。カスケードでパーティクル システムを作成する際は、この 3 つのプロセスすべてについて考慮することが重要です。

また、カスケードは、ゲームスレッド上でパーティクルの評価を行いますが、ゲームスレッドはゲームプレイが計算される場所でもあることに注意すべきです。

オーバードロー - GPU

マテリアルをスプライトのサーフェスに追加する場合、マテリアルの命令数に応じて負荷がかかります。透過オブジェクトでは、透過処理が積み重なってオーバードローを作るため、命令による負荷がかさみます。透過処理のレイヤーが増えるにしたがって、負荷が高くなります。ごく簡単にオーバードローについて説明すると、次のようになります。

オーバードロー = ピクセルシェーダーの負荷 = レイヤー数 × 影響を受ける平均ピクセル数

この負荷は、 Shader Complexity モード のビューモードを使って簡単に表示することができます。明るい赤= 300 命令、ピンク= 600 命令、白 >= 900 命令。PC 上でシェーダー複雑度を表示するには、 Alt+8 キーを押します。

マテリアルの命令カウントは、マテリアル エディタで見ることができます。

シェーダー複雑度のビューモードによって、システムのおよその負荷が算出されますが、この負荷はシーンにも依存します。透過処理が、やはり負荷をもつ不透明なオブジェクトに対して計算されるからです。

エフェクトの使用法をチェックすることは、非常に重要です。通常、任意のシナリオ (武器の衝撃) で呼び出されるエフェクトは、カスタムビルドすることによって、特定のシナリオにマッチさせるようなエフェクトよりも軽くなければなりません。理由は、負荷が変動するシナリオで描画されるためです。

オーバードローの影響を制御するために取りうる処置は、次のようになります。

  • エミッションのレートを下げる。

  • マテリアルの命令数を減らす。

  • パーティクルのスケールを下げる (スクリーンのより狭い範囲を満たす)。

  • 近く / 遠くのパーティクルエミッションのための LOD を作成することで、様々な視界距離における負荷を下げる。

  • 一列に配置されたエミッタが、互いに重なり合っていないかチェックする。(静的な、配置されたエフェクト)。

LODs - Level of Detail (詳細度) - GPU / ゲームスレッド

カスケードで LOD を使用することで、プレイヤーからエミッタまでの距離に基づいて、モジュールとビヘイビアを制御することができます。パーティクル システムのどの属性 (attribute) であっても変更することで、LOD システムを使用できます。

LOD 設定に関する技術的な詳細は、 カスケード リファレンス ガイド パーティクル システム LDO のセクションを参照してください。

LOD を作成する場合は、共有されていないモジュールに関連してメモリの負荷が生じることに留意しなければなりません。複数の LOD でできる限り多くのモジュールを共有すると、メモリの使用量を減らすことができます。ユニークなモジュール設定項目を作成するのは、属性を変更する場合にのみ行うようにします。

detailModes.png

カスケードのプレビューモードとエディタのパースペクティブ (透視図法) ビューは、様々な点でビヘイビアが異なります。カスケードで適切に表示させるには、以下の設定を行うようにしてください。 [View (表示)] -> [Detail Mode (詳細モード)] [High] に設定します。

カスケードでは、LOD を切り替えて指定した LOD を表示することができます。カスケードを正しく更新させるには、エディタの LOD ビューモードを必ず無効にしなければなりません。

エディタのプレビューを有効にすると、シーン内をすばやく移動し、パーティクル システムがその移動に合わせて複数の LOD を切り替える様子を表示させることができます。

シーンを測定し、適切な状態でエフェクトを表示させるのに必要となる単位数について、実際的な値を得ることが大切です。アンビエント パーティクル システムの場合は、パーティクル システムが見えないときに、0.00 のパーティクルをエミットし、ティック時間を減らすことが可能です。距離を測定するには、マウスボタンをのホイールを押下したまま、いずれかの正投影ビュー (正面、側面、上面) にドラッグします。

LOD Distance Check Time (LOD 距離チェック時間)

LOD Distance Check Time 機能は、プレイヤーからシーン内に配置されたエミッタまでの距離をゲームがチェックする頻度を規定します。この距離は、使用すべき LOD を決定するために使用されます。LOD Distance Check Time (LOD 距離チェック時間) は、その LOD Method がAutomatic (自動) に設定されている場合に有効です。

基本的に、Automatic に設定することで、LOD がゲームによってプレイ時に決定されます。この LOD Distance Check Time (LOD 距離チェック時間) を大きくすると、チェックの間隔が長くなります。LOD Distance Check Time (LOD 距離チェック時間) は秒単位で計算されるので、これを設定する場合は、プレイヤーの最大移動速度を考慮する必要があります。LOD Distance Check Time (LOD 距離チェック時間) を 0.00 の値に設定すると、距離がフレームごとにチェックされることになり、パフォーマンスは低下します。

LOD のメソッド - ゲームスレッド

パフォーマンスとビジュアルにとって、LOD のメソッドを適切に設定することは不可欠です。

Automatic (自動) - ゲームが、LOD Distance Check Time (LOD 距離チェック時間) の設定を使用して、エフェクト内で定義された距離パラメータに基づき LOD 設定します。通常、ゲームコードによって呼び出されないループするアンビエント (環境) エフェクトで使用されます。

Direct Set (直接設定) - エフェクトが、定められた LOD にスポーンされてとどまっている場合に、(通常はゲームコードによって) LOD が決定されます。普通は、爆発や衝撃などのバースト エフェクトで使用されます。

Activate Automatic (自動のアクティベート) - LOD で定義された距離パラメータに基づき、エフェクトがスポーンされたときに LOD が定義されます。通常、いったんスポーンされると LOD を二度と変更する必要がない、ブループリントなどによって呼び出される突発的なエフェクトで使用されます。

固定境界と非固定境界 - ゲームスレッド

境界 (bound) は、エンジンがエフェクトのビジビリティ (表示 / 非表示) を決定できる方法の 1 つです。そのような目には見えない座標によって、エフェクトが表示されるのか表示されないのかを、エンジンが把握することができるのです。境界の隅がビジブル (表示) になっている場合は、エンジンが、必要なエフェクトのあらゆるコンポーネントを計算します。

フレームごとにチェックおよび更新される境界は、負荷が高くなります。したがって、境界を固定 (fixed) に設定セットして、必要な境界の大きさを決定することが重要となります。たとえば、爆発から飛び散った残がいをすべて表示しなければならない場合などでは、境界をかなり大きくする必要があります。負荷を抑えるには、境界を中心となるコンポーネントに制限することによって、パフォーマンスを向上させることができます。ただし、その場合、境界が視界領域から外れた場合に、エフェクトが突然非表示になるという欠点があります。

固定境界にすべきか非固定境界にすべきかを決定するには、考慮しなければならない事項がいくつかあります。

ロケットのトレイル (ロケット雲) や追跡物、発射物に付属するものなどの高速で動かすエフェクトには、固定境界を設定すべきではありません。あるいは、エミッタが境界の外に飛んで行けないような大きな固定境界を設定しないようにすべきです。

境界を設定する場合は、システムで定義されているワールド空間座標とローカル座標について注意を払わなければなりません。エミッタが境界の向きと反対の方向に回転している場合は、エフェクトの要素が、境界の外に飛び出してしまい、要素が視界領域から突然消えてしまう可能性があります。

描画コール - レンダリング スレッド

パーティクル システム内の描画コールは、たまに追跡が難しいことがあります。描画コールの負荷を計算する場合は、複数の要因がからんでいることに留意すべきです。

スプライトのパーティクル エミッションは、スクリーンの向きにかかわらず、エミッタにつき 1 描画コールにあたります。

メッシュ エミッションは、エミットされるメッシュ数に関係なく、エミットされるメッシュにつき 1 描画コールにあたります。しかし、モバイル デバイスでは、負荷は エミットされる メッシュにつき 1 描画コールにあたります。したがって、モバイル デバイスでは、エフェクト内にある 2 つのエミッタがそれぞれ 10 個のメッシュをエミットした場合、そのパーティクル システムに対して合計 20 描画コールの負荷がかかることになります。

マテリアルのパスも描画コールの負荷にかかわります。マテリアル内でパスが多くなるにつれて、エフェクト内の描画コールも多くなります。

例:

  • パーティクル システム A の構成が、パスが 1 つのマテリアを使って 12 のスプライトをスポーンするエミッタ 1 つの場合、パーティクル システム全体の負荷は、1 描画コールということになる。

  • パーティクル システム B の構成が、パスが 2 つのマテリアルを使って 12 のスプライトをスポーンするエミッタ 1 つの場合、パーティクル システム全体の負荷は、2 描画コールということになる。

  • パーティクル システム C の構成が、パスが 2 つのマテリアルを使って 12 のメッシュをスポーンするエミッタ 1 つの場合、

    • モバイル プラットフォーム上 では、パーティクル システム全体の負荷は、24 描画コールということになる。(1 コールにつき 2 パス × 12 メッシュ (各メッシュは 1 描画コールであるため) = 24 描画コール)

    • 他のすべてのモバイル プラットフォーム上 では、パーティクル システム全体の負荷は、2 描画コールということになる。

  • パーティクル システム D の構成が、パスが 2 つのマテリアルを使用して、6 のメッシュ をスポーンするエミッタ 1 つ、および、パスが 1 つのマテリアルで 10 のスプライトをスポーンするエミッタ 1 つの場合、(1 コールにつき 2 パス × 6 メッシュ (各メッシュは 1 描画コールであるため) = 12 描画コール、1 パス × 10 スプライト = 1 描画コール)。

パスに寄与するマテリアルの属性には、以下のようなものがあります。

透過マテリアル = 1 パスベース

  • 歪み (distortion) は、+2

  • bUseLitTranslucencyDepthPass (光源処理透過デプスパスを使用する) は、+1

  • bUseLitTranslucencyPostRenderDepthPass (光源処理透過性ポストレンダリング デプスパスの使用) は、+1

  • bUsedWithFogVolumes (フォグ ボリュームとともに使用) は、+2

不透明 / マスク化マテリアル=2 パスベース

特定のシーンのための描画コールを表示するには、 DumpParticleFrameRenderingStats (パーティクル フレーム レンダリング統計のダンプ) コマンドを使用します。このコマンドは、描画コールの負荷を詳細にリスト表示したスプレッドシートを出力します。

描画コールによる影響は、レンダリングされているビューの数に比例して強まります。つまり、分割スクリーンでは、その影響が倍になるということです。分割スクリーンのエフェクト最適化に関する詳細は、 VFX の最適化ガイド分割画面 のページを参照してください。

エフェクトを作成する、およびエフェクトを最適化する場合は、上記の負荷に留意することが大切です。描画コールのためレンダリング スレッドが高負荷で、かつその環境が負荷配分内にある場合は、見直しの検討が必要です。

メッシュ エミッション - ゲーム スレッド / レンダリング スレッド

メッシュ エミッションは、カスケードがもつ非常に強力な機能の 1 つです。エミッション レートは、描画コールの数と等しいため、モバイル デバイスで誤使用の可能性のある機能でもあります。さらに、メッシュ上にある頂点の数を多くしないことも、有効です。

場合によっては、単一のメッシュ エミッションを使用することで、インスタンスのために大量の残がいを作成するのに必要な全スプライトの位置を計算するという負荷をかけずに、多量のオブジェクトをフェイクすることが可能となります。

CPU コリジョン - ゲーム スレッド

CPU パーティクル コリジョンは、通常 UE4 において高い負荷がかかるため、必要な場合に限って使用するようにしてください。

コリジョンの負荷を最小に抑えるために使用できる設定項目には、次のようなものがあります。

  • MaxCollisions (最大コリジョン) : この値をできるだけ小さくします。

  • Collision Completion Option (コリジョン完了オプション) : これを HaltCollisions/Freeze (コリジョン停止 / フリーズ) に設定することによって、MaxCollisions (最大コリジョン) に達したときにシーンのコリジョンチェックを中止させます。

  • Damping Factor (減衰係数) によって、コリジョンに続いて起きるオブジェクトの跳ね返り (bounce) が決定されます。この値が低くなるほど、オブジェクトの静止が早くなります (MaxCollisions の値を低めます)。

Spawn Per Unit (単位あたりのスポーン) - GPU/ゲーム スレッド

Spawn Per Unit (単位当たりのスポーン) は、パーティクル システムが動いているときにギャップをフィル (fill) するのに役立つ Cascade の機能です。見栄えがするパーティクルのトレイル (trail) を作るのに便利な機能ですが、使用する場合はパフォーマンス上の制限とビジュアルのバランスを取ることが重要です。

エミッションをコントロールするには、いくつかコツがあります。

  • Unit Scalar (単位スカラー) をできるだけ高い値に保つとともに、この値とエミッションレートとのバランスを取ることによって、エフェクトを重くしすぎずに、必要なフィルが得られるようにする。

  • Spawn Per Unit (単位当たりのスポーン) を使用して高いエミッションレートになることが分かっている場合は、なるべく少ない命令のマテリアルを使用する。

  • Max Frame Distance (最大フレーム間隔) を調整して、エミット可能なパーティクルの数を制限する。エミッタがこの Max Frame Distance (最大フレーム間隔) を超えた場合は、その間隔を下回るようになるまで、Spawn Per Unit (単位当たりのスポーン) がミッションを中止します。これによって、エミッタが大量のスプライトをシーンにダンプしないようになります。

メモリの負荷

カスケードには、パーティクル システムの作成にかかわる貴重な情報を大量に表示できる機能が備わっています。この表示機能を有効にすると、システムで割り当てられているパーティクルの数およびシステムがエミットしているパーティクルの数を適切に把握できるため、役立つことが多いです。

Particle Allocation (パーティクルの割り当て) によって、エミッタが任意の時間にワールド内に配置できるパーティクルの数が決まります。これは、パーティクル システムによって消費されるメモリを計算するのに大いに役立ちます。メモリの概算を見るには、カスケード内の [View] ドロップダウン メニューで、パーティクルのメモリ オーバーレイ表示を有効にします。

設定値を調整することによって、メモリの負荷の増減を確認することができます。

メモリ使用量は、以下の方法で減らすことができます。

  • システム内にあるモジュールの数を、当該ビヘイビアのために必要不可欠なモジュールの数まで減らす。

  • ループエフェクトについては、Loop Time/Duration (ループ時間 / 期間) を減らす(ループ当たりのパーティクル割り当て数を減らす)。

  • ライフタイム を減らす(全体としてのパーティクル数を減らす)。

  • できるかぎり多くのモジュールを共有する。

カスケードの特徴として、あるエミッタから別のエミッタへとモジュールを共有させる機能があります。この機能には 2 つの利点があります。第一に、複数のエミッタにまたがって値を編集したい場合に、1 個のモジュールを編集して残り全部のモジュールの設定を更新させることができます。第二に、モジュールを共有化することによってメモリ使用量が減ります。これは、クック済みバージョンが、モジュールの負荷をモジュールの 1 個のインスタンスとして見なすためです。

最近になってクッカに追加された機能を使用すると、パーティクル システム内のモジュールをすべて評価して同一モジュールを判定し、さらに、自動的にモジュールを共有化することによって、メモリ使用量をクック時に減らすことができます。

ティック時間 - ゲーム スレッド

Tick Time (ティック時間) は、シーン内でパーティクル システムを更新するのに費やされた時間です。Tick Time は stat particles (統計パーティクル) コマンドを使用して見ることができます。このコマンドは、パーティクルの評価コストを見積もるために必要な関連情報をすべてリスト表示するものです。

Tick の負荷を減らすには、多数の方法があります。

Tick Time は、シーン内のアクティブなエミッタ アクタの数から直接影響を受けます。シーン内にアクティブなエミッタが増えるほど、Tick Time は大きくなります。エミッタは、レベルがスタートしてループしなければならない場合、必ず autoActivate (自動アクティベート) にのみ設定されるべきです。

大量のスプライト / 爆発 / バーストエフェクトが、エディタ内でレベルロード時にビジブル (可視的) になっているならば、これらのエフェクトは自動的に実行時に評価されて、レベルがロードされると処理落ちが目につく場合があります。

エフェクト内でパーティクル パラメータを使用することで、エフェクトがワールド内に配置されると、位置のオフセットが可能になります。パーティクル パラメータを使って、エミッタの数を減らすことができるため、Tick の全体的な負荷を下げることができます。パーティクル パラメータは、個々の設定項目のためのモジュール内にある [disitribution] リストから Particle Parameter を選択することによって設定できます。

エミッタ アクタ は、視界に入っていない場合や、もはやメモリにないレベルの部分に関係する場合に、ストリームアウトして無効にすることができます。レベル ジオメトリとともに エミッタ アクタ をストリームすることによって、Tick のオーバーヘッドを減らすのは、有効なやり方です。大気に関する (atmospheric) エフェクトが重い場合には、ブループリントのアクションを使用して、戦闘中に大気 (atmosphere) の on/off を切り替えることによって、Tick Time とオーバードローを抑えることができます。

パーティクル システムがメモリにロードされているものの、視界から外れている場合 (たとえば、上の階にあるなどの場合) は、ブループリントのアクションとボリュームのストリーミングでそのパーティクル システムを切り替えることによって、評価コストを減らすことができます。

メッシュ エフェクトをパーティクル システムの代わりに使用することが適している場合があります。配置されたスタティックメッシュは、ゲームスレッド上で評価コストがかかりません。スタティックメッシュをパーティクルシステムの代わりに配置した方が多くの場合においてより有益です。これには、眺望 (vista) エフェクトやフォグ (fog) エフェクトなどが含まれます。

パーティクルの数は評価コストに直接影響します。シーン内でパーティクルの数が増えれば、また、パーティクルが長く生き続ければ、その分だけ一層評価が必要となります。ライフスパンを、エフェクトに必要な期間だけに限定することは、あらゆる点で効果的です。

パーティクル システム内で LOD を有効にすることによって、システムが最適な視界の範囲から外れている場合に、パーティクル エミッションを下げることができます。主人公の視点からエフェクトを検討し、視距離遠くにある場合に容認可能なクオリティ低下のレベルについて考えることが、役立つ場合があります。LOD を必要な距離に厳格に合わせれば、ビジュアルのクオリティを劇的に低下させることなく、シーン内で評価コストを下げるのに役立ちます。

下げることができる高価な評価コスト (たとえば、コリジョン、非固定境界、高すぎる負荷の単位当たりのスポーンなど) について、エフェクトを点検してみましょう。境界を固定した状態にセットすることで、パフォーマンスを著しく向上させることができます。可能な場合は常にこれを利用すべきです。

Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
キャンセル