UI の無効化

変更時に再計算と再描画を行うウィジェットを選択してマークすることで、CPU 使用率を節約することができます。

Choose your operating system:

Windows

macOS

Linux

無効化 は、ウィジェットの再描画の頻度を制限することで、UI の CPU 使用率を削減するシステムです。無効化システム内のウィジェットが UI 内のレイアウトを変更すると、それらは 無効化 としてマークされます。その後、無効化されたウィジェットとその子ウィジェットだけが再描画されます。

プロジェクトで無効化を使用するには、2 つの方法があります。

  • [Invalidation Box (無効化ボックス)] ウィジェットと [Retainer Panel] ウィジェットを使用して、ウィジェット単位で無効化を実装する。

  • Global Invalidation (グローバルな無効化) を使用して、UI 全体に無効化を実装する。

以下のセクションでは、プロジェクトに無効化を実装する方法と、無効化を適用する場所を決定できるようにするための仕組みについて説明します。

無効化を実装する方法

Invalidation Box (無効化ボックス)

Invalidation Box ウィジェットは、子ウィジェットのジオメトリをキャッシュし、それらのウィジェットに変更がないか監視します。無効化ボックス内のウィジェットが変更されない限り、スレートは再描画せずにキャッシュされたジオメトリにフォールバックするため、ウィジェットの CPU 使用率が大幅に削減されます。

UMG エディタの パレット[Optimization (最適化)] セクションに [Invalidation Box] ウィジェットがあります。

The optimization section in the UMG widget palette.

無効化ボックスは、それがラップされているすべてのウィジェット、および階層内のすべての子ウィジェットを処理します。

無効化ボックスとその設定の詳細については、「無効化ボックスウィジェットリファレンス」を参照してください。

Global Invalidation (グローバルな無効化)

グローバルな無効化は、SWindow の無効化機能を有効にし、UI 全体を効果的に無効化ボックスでラップします。そのウィンドウに含まれるすべての無効化ボックスは無効となり、SWindow だけが情報をキャッシュします。

Slate.EnableGlobalInvalidation を true に設定することで、グローバルな無効化を有効にすることができます。

Retainer Panel

Retainer Panel は、ユーザーの画面にレンダリングする前に、すべての子ウィジェットを 1 つのテクスチャに平坦化します。さらに、以下のオプションで、Retainer のレンダリング方法を設定することができます。

  • フェーズ ベースまたはフレームレート制限レンダリングを使用すると、それぞれの保持パネルが別々のフレームに描画されるように設定され、スレートは UI 全体を同時に描画しないようになります。

  • 異なる Retainer パネルに異なるフレームレートを設定します。例えば、UI のある部分は 30FPS で、他の部分は 60FPS で動作させることができます。

これらはすべて、UI が 1 つのフレームで行う描画の呼び出し回数を減らす、または管理するための機能です。

再描画時における Retainer パネルのオーバーヘッドは高く、無効化ボックスを使用した場合の個々のウィジェットよりも多くのメモリを使用します。これは、各 Retainer パネルが、個々のウィジェットの無効化データを使用するだけでなく、独自のレンダリングターゲットを持つためです。使用率の削減対象を探すには、まず無効化ボックスを使用する必要があります。描画呼び出しの追加削減が必要な場合は、Retainer を実装すればさらに凝縮することができます。これは、ローエンドのモバイル デバイスのように、パフォーマンス バジェットが特に厳しい環境で役に立ちます。

無効化のしくみ

ウィジェットが画面上に描画されるとき、いくつかの計算が次の順序で行われます。

  1. 階層: スレートは、ルート ウィジェットとその子ウィジェットを含む、階層内のウィジェットのツリーを構築します。

  2. レイアウト: スレートは、レンダリング変換に基づいて、ウィジェットのサイズと画面上の位置を計算します。

  3. ペイント: スレートは、個々のウィジェットのジオメトリを計算します。

このプロセスの各ステップは、その後に続くすべてのステップを通過する必要があります。たとえば、レイアウトの計算には「ペイント」ステップを実行する必要があり、階層を再構築するにはペイントとレイアウトの両ステップを実行する必要があります。

無効化システムは、上記の各データをウィジェットの親である無効化ボックス、またはグローバル無効化を使用している場合は描画される SWindow にメモリとしてキャッシュします。キャッシュされた情報が変更されない限り、スレートは計算のやり直しを行わずに、キャッシュされた情報を使用します。ウィジェットが変更されるたびに、ダーティリストに追加されます。次のレンダリングフレームで、ダーティなウィジェットはすべて、変更されたデータの種類に応じて再計算されます。

無効化には、再計算と描画処理でスキップする部分に対応するタイプがいくつかあります。

無効化タイプ

CPU コスト

説明

Volatile/Visibility

非常に低い

Is Volatile または Visibility フラグは、ウィジェットとその子で変更されます。

Paint

ウィジェットのジオメトリが再計算されます。これは、色やマテリアルなどの非レイアウトパラメータを変更した場合に発生します。

Layout

ペイント無効と同様に、画面上のウィジェットのサイズと位置が変更されます。これは、ウィジェットのレンダリング変換を変更した場合に発生します。

Child

スレートは、レイアウトの無効化の他に、子ウィジェットのリストを再構築します。これは、ウィジェットとその子の完全な再計算を必要とし、ウィジェットから子を追加または削除した場合に発生します。

これがプロジェクトにどのように影響するかの例として、ウィジェットの色だけを変更した場合、そのウィジェットの Paint Invalidation (ペイントの無効) がトリガーされます。スレートは、子ウィジェットのリストとレイアウトの再構築をスキップし、ジオメトリの再計算のみが必要になります。キャッシュされたレイアウト データは有効なままなので、更新する必要はありません。

コードまたはシーケンサー アニメーションでウィジェットを移動またはサイズ変更すると、Layout Invalidation (レイアウトの無効化) がトリガーされます。レイアウトデータ (位置とサイズ) とペイントデータ (ウィジェットのジオメトリ) を含め、ウィジェットのキャッシュされた情報は、これが起こるたびに再計算される必要があります。これは、子プロセスの無効化と比較するとかなり高速です。

ウィジェットの子を追加または削除すると、Child Invalidation (子の無効化) が発生します。子リストを再構築した後、ウィジェットとその子すべてについて、レイアウトとペイントの計算を更新する必要があります。ほとんどの使用例では、これは 1 フレームのコストで価値がありますが、UI がフレームごとにこれを行う場合、かなりのパフォーマンスのボトルネックになる可能性があります。

Volatile/Visibility の無効化 は、Is Volatile フラグまたは Visibility フラグが変更されたときにのみ適用されます。これらの状況のどちらかが、次のフレームでウィジェットを再描画する必要がありますが、必ずしも他のデータが無効であることを意味するわけではありません。詳しくは、以下の「Volatile Widgets」のセクションを参照してください。

無効化は、頻繁に変更されないウィジェットに特に適しています。スレートは、長期間にわたってキャッシュされたデータを使用できるため、UI の CPU 負荷が大幅に軽減されます。これは、MMORPG や深いメニューのあるライブサービスゲームのような、大規模で複雑な UI を作成する場合に特に重要です。

Volatile Widgets (揮発性ウィジェット)

時には、非常に頻繁に、場合によってはフレームごとに更新する必要があるウィジェットを実装する必要がある場合があります。この場合、ウィジェットは変更するたびに無効化を行います。これは、ウィジェットが無効化をまったく使用しない場合と同じ CPU 負荷を使用する可能性がありますが、ウィジェットのジオメトリをキャッシュするために必要なメモリはいずれにせよ消費されます。

この問題に対処するために、頻繁に更新するウィジェットを Volatile ウィジェットとしてマークすることができます。ウィジェットが Volatile としてマークされると、無効化システムはそのペイント・データおよびその子のペイント・データをキャッシュしなくなります。ジオメトリはフレームごとに再計算され、再描画されますが、スレート必要な場合を除き、レイアウト計算をスキップします。これは、UI 全体に広く無効化を適用したいが、更新頻度が高いためにキャッシュの恩恵を受けない一部のウィジェットを調整したい場合に役立ちます。

ウィジェットを Volatile としてマークするには、ウィジェットの [Details (詳細)] パネルで [Performance] > [Is Volatile] の設定を切り替えてください。

The Is Volatile setting in a widget's Details panel

また、C++では、Volatile パラメータを true に設定することで、ウィジェットを Volatile としてマークすることができます。