手動の PSO キャッシュでは、ゲームのビルドをプレイして PSO(Pipeline State Object)の情報をバンドルキャッシュに収集する必要があります。 PSO プリキャッシングは、レンダリング中に使用可能なすべての PSO を自動で収集し、非同期でコンパイルします。
PSO 事前キャッシュを設定する
次のコンソール変数は、PSO プリキャッシングを制御します。
| コンソール変数 | 説明 | デフォルトの状態 |
|---|---|---|
| PSO プリキャッシングを有効にするグローバル コンソール変数。 これは RHI フラグ | 有効化済み |
| コンポーネントで使用される PSO を事前キャッシュします。 | 有効化済み |
| すべてのリソース ( | 無効 |
| すべての必要な PSO がコンパイルされるまで、コンポーネント プロキシの作成を待機します。 プロキシの作成時にまだコンパイルしている場合、それらは優先度の高い PSO としてマークされます。 | 有効化済み |
| コンポーネントのプロキシを作成中にまだ PSO をコンパイルしている場合、マテリアルをデフォルトのマテリアルに置き換えるオプションが追加されます。 これは、 | 0 (下記参照) |
| ロード中、優先度の高い PSO のみを待機します。 必須でない PSO はすべて、ゲームプレイ中にコンパイルされます。 PSO がプロキシで必要になり、まだコンパイルされていない場合は、優先度が高くマークされます。 | 無効 |
| グローバル コンピュートおよびグラフィック PSO も、エンジンの起動時に事前キャッシュするかどうかを指定します。 | 有効化済み |
グローバル シェーダ PSO 事前キャッシュ
特定のグローバル シェーダ PSO は、初回使用時にランタイムの処理落ちが発生する可能性があるため、事前キャッシュされます。 これらの PSO はエンジンの起動時にコンパイルされ、r.PSOPrecache.GlobalShaders コンソール変数を使用してデフォルトで有効になります。
ゲームで使用できる、すべてのグローバル コンピュート シェーダ順列が事前キャッシュされます。
static EShaderPermutationPrecacheRequest ShouldPrecachePermutation(const FShaderPermutationParameters& Parameters)これは、現在のコンソール変数設定をチェックして特定の組み合わせを除外することで、指定された順列がランタイム時に使用できるかどうかを確認します。 デフォルトでは ShouldCompilePermutation を使用するため、事前キャッシュの順列はコンパイルされた順列のサブセットである必要があります。
グローバル グラフィック PSO のほとんどは、ロード直後の最初の数フレーム中に作成され、ヒッチはこれらのフレームで気づくことができます。 非常に小さい PSO バンドル キャッシュを使用してこれらのグローバル グラフィック PSO を収集すると役立つ場合があります。 ただし、特定のグローバル グラフィック PSO 順列もランタイム時に作成され、コンパイルされるため、これらも事前キャッシュする必要があります。 グローバル グラフィック PSO の場合、グラフィック PSO のコンパイルに必要なすべての正しいレンダリング状態を収集するために、特定の PSO コレクターが必要となります。
現在、PSO 事前キャッシュは次のグローバル シェーダー型に実装されています。
スレート
ディファード ライト
カスケード パーティクル シミュレーション
ボリュメトリック フォグ
起動時にすべてのグローバル PSO をコンパイルするのは時間がかかります。通常、メインメニューのナビゲート中に行われます。 これによって起動時にエンジンはブロックされませんが、最初のロード画面時の PSO コンパイルの待機フェーズの一部に含める必要があります。
コンポーネント PSO 事前キャッシュ
プリミティブ コンポーネント (UPrimitiveComponent) では、ロードの直後 (PostLoad 実行中) にレンダリングに必要となるすべての PSO を事前キャッシュします。 事前キャッシュでは、次のような PSO のコンパイルに必要なすべてのパイプラインの状態情報を収集します。
マテリアル
頂点ファクトリ
頂点要素情報
特定のプリキャッシュ パラメータ
Unreal Engine は、コンポーネントをレンダリングできるすべての可能なメッシュパス プロセッサ全体をイテレートするためにこの情報を使用します。 各メッシュ パス プロセッサは、レンダリング中に必要になることがある PSO 初期化子を追加します。 バックグラウンドタスクでは、共有されている PSO キャッシュをチェックして、必要なデータがすでにプリキャッシュされていないことを確認し、これらのリクエストを非同期でコンパイルします。
1 つのコンポーネントをさまざまなパス (ベース、カスタム深度、深度、歪み、シャドウ、バーチャル シャドウ マップ、ベロシティ など) で正しくレンダリングするためには、多数の PSO が必要になる場合があります。 コンポーネントが準備できる前に、これらすべての PSO を準備しておくことが重要です。そうしないと、例えばあるパスでレンダリングされ、別のパスではレンダリングされない可能性があるからです。
UE でプリミティブ コンポーネント向けにプリミティブ プロキシを作成し、それに必要な PSO がまだコンパイルされている場合、次のようなオプションを利用することができます。
PSO のコンパイルが完了するまで、プロキシの作成を遅延する (デフォルト)。 これにより、PSO の準備が整うまで描画がスキップされます。
マテリアルをエンジンのデフォルト マテリアルに置き換えます。
実行を継続するため、ヒッチの可能性がある。 描画により、PSO のコンパイルがブロックされます。
プロキシ作成の遅延戦略
r.PSOPrecache.ProxyCreationDelayStrategy コンソール変数は r.PSOPrecache.ProxyCreationWhenPSOReady コンソール変数に依存しています。 ProxyCreationWhenPSOReady が 1 (有効) に設定されている場合、ProxyCreationDelayStrategy はその値に応じて次の動作を実行します。
| 値 | 動作 |
|---|---|
0 | PSO の準備が整うまで描画がスキップされます。 |
1 | PSO の準備が完了するまで、エンジンのデフォルト マテリアルにフォールバックします。 |
ロード画面
PSO 事前キャッシュ リクエストを念頭に置いて、最初のロード画面を設定することを強く推奨します。 。
ゲームの初期ロード画面を設定する際は、現在未処理のすべての PSO 事前キャッシュ要求を待機させる必要があります。 そうしない場合、遅延プロキシ作成がサポートされていないコンポーネント(ランドスケープ テレインなど)で、顕著なポップやランタイム ヒッチが発生する可能性があります。そのような場合、これらのメッシュをデフォルト マテリアルに置き換えたり、レンダリングしないことは推奨されません。
FShaderPipelineCache::NumPrecompilesRemaining() は、バンドル キャッシュと PSO 事前キャッシュの両方で、未処理の PSO 事前キャッシュ コンパイル数を確認するのに有用です。 ロード画面のロジックを変更し、この数値をチェックして、ゼロになるまでロード画面を表示し続けることができます。 ほとんどの場合、空のドライバー キャッシュを使用した初回の PSO コンパイル時間は、中程度のスペックの CPU で 1 分未満です。
システム リソースを管理する
PSO 事前キャッシュはバックグラウンド スレッドを使用する非同期コンパイルに依存し、システム メモリとパフォーマンスに影響を与えます。 このセクションでは、プロジェクトに合わせてこれらのリソースの使用を調整および最適化するために利用可能なオプションについて説明します。
メモリ
ランタイム システム メモリを節約するため、UE ではコンパイル後に事前キャッシュ用にコンパイルした PSO を削除します。 これは、アプリケーションによって事前キャッシュされた PSO の量が非常に多い場合、クリーンアップしない限り、アプリケーションのメモリフットプリントが大幅に増加する可能性があるためです(数百メガバイト、または数ギガバイト)。
PSO 事前キャッシュは、基盤となる圧縮されたドライバ キャッシュの存在に依存します。 事前キャッシュ後に PSO が削除されても、ドライバ キャッシュには PSO が保持されています。 ランタイム時に PSO が必要となる場合は、グラフィック ドライバによって圧縮されたドライバ キャッシュからロードされます。 ただし、これはリソースを大量に消費する可能性もあり、これらのキャッシュからの最初の取得には、数ミリ秒かかる場合があります。 D3D12.PSOPrecache.KeepLowLevel を使用して、D3D12 で事前キャッシュ済みの PSO の削除を無効にすることができます。
ドライバ キャッシュからの PSO 作成は、特定の独立系ハードウェア ベンダー (IHV) では速度が低下することがあります。 NVIDIA の場合、rr.PSOPrecache.KeepInMemoryUntilUsed を使用して、一定量の事前キャッシュされたグラフィックスおよびコンピュート PSO をメモリに保持できます。これにより、最後の N 個の事前キャッシュ PSO をメモリに維持し、ドライバ キャッシュのパフォーマンス低下を回避します。 メモリに保持される PSO の数は、コンピュート用とグラフィック用に r.PSOPrecache.KeepInMemoryGraphicsMaxNum と r.PSOPrecache.KeepInMemoryComputeMaxNum を使用して調整することができます。 このオプションを使用する場合は、さまざまな設定でアプリケーションのメモリ使用量をテストし、PSO 作成のパフォーマンスとメモリのオーバーヘッドとの間の許容可能なトレードオフを決定することをお勧めします。
Performance (パフォーマンス)
デフォルトでは、Unreal Engine は PSO 事前キャッシュ スレッド プールを使用して PSO を非同期でコンパイルします。 r.pso.PrecompileThreadPoolSize または r.pso.PrecompileThreadPoolPercentOfHardwareThreads が設定されている場合、スレッド プールが使用されます。 それ以外の場合、PSO のコンパイルはエンジンの他のワークロードと共にスケジュールされる通常のバックグラウンド タスクにフォールバックします。
| コンソール変数 | 説明 | デフォルトの状態 |
|---|---|---|
| プールで使用するスレッドの正確な数を設定します。 | 0 |
| スレッド プールのサイズを利用可能なハードウェア スレッドに対する割合で設定し、そのサイズのスレッド プールを作成します。 デフォルト サイズは 75 です。これはハードウェア スレッドの 75% を表します。 | 75 |
| PSO スレッド プールで使用するスレッドの最小数。 | 2 |
| PSO スレッド プールで使用するスレッドの最大数。 デフォルトは、最大数を設定しない場合の | INT_Max |
追記:
スレッド プールの最大スレッド数を無制限にした場合、多数のプロセッサを備え、メモリはそれほど多くないシステムで PSO をコンパイルしている間に、システム メモリが不足する可能性があります。 PSO をコンパイルする各スレッドは最大 2 GB のメモリを使用することができるため、プロジェクトではこの量を制限することが合理的です。
ゲームプレイ中にハードウェア スレッドの 75% を使用すると負荷が高くなる可能性があります。 通常のフォアグラウンド スレッドとの競合が顕著で、若干のフレーム ドロップを引き起こします。 ロード時にこの値を大きくし、ゲームプレイ中に再度小さくすると解決することがありますが、PSO のコンパイルが遅延し、遅延プロキシ作成が増加する可能性がありますが、ランタイムヒッチは発生しません。
コマンドライン引数 -clearPSODriverCache を使用して、強制的にドライバ キャッシュをクリアできます。これは、初めてゲームを起動するエクスペリエンスをテストする場合にお勧めします。
コア数の多い PC でテストを行う場合は、コマンドライン引数 -corelimit=n を使用して、コア数を 8 または一般的なコンシューマー向け PC のコア数に制限することを推奨します。ここで、n はコアの数です。さらに -processaffinity=n も併用することで、Windows はゲームを n 個の物理コア上のみにスケジュールするようになります。 これにより、最終的なユーザー エクスペリエンスをより正確にレプリケートすることができます。
ゲームのスムーズさを評価するすべてのテストで、一貫して -clearPSODriverCache スイッチを使用してください。 使用しない場合、グラフィック ドライバによってビルドされ、以前の実行で残った PSO キャッシュによってヒッチがマスクされることがあります。
検証とトラッキング
PSO 事前キャッシュ システムのパフォーマンスを検証およびトラッキングするためのオプションがいくつかあります。
次の値で r.PSOPrecache.Validation を使用すると、検証を有効にすることができます。
| コンソール変数 | 説明 |
|---|---|
0 | 無効 |
1 | 高レベルの数値のみを使用する軽量トラッキング。 これはパフォーマンスへの影響がほとんどないため、製品版タイトルでも使用できます。 |
2 | PSO 事前キャッシュのミスに関する詳細な追跡とログ記録が可能です。 |
PSO 事前キャッシュ検証が有効な場合、stat PSOPrecache コンソールコマンドを使用して収集された統計情報を確認できます。
これは、PSO プリキャッシュ検証システムによって収集された統計情報です。 stat PSOPrecache コンソールコマンドで表示できます。
統計データは 3 つのグループに分割することができます。
| グループ | 説明 |
|---|---|
シェーダーのみの PSO | これらの統計は、使用されている RHI シェーダーのみをトラックし、PSO 内の他の情報はすべて無視します。 これは、少なくともすべてのシェーダーが事前キャッシュされているかどうか、他のレンダリング状態で何かが欠如していたり誤りがあったりしないかを確認する場合に便利です。 |
最小 PSO | シェーダーと、レンダー ターゲット情報を除くすべてのレンダリング統計および頂点要素情報を含みます。 レンダー ターゲット情報は描画時の検証でのみ利用可能ですが、最小 PSO 統計は MeshDrawCommand ビルド中に更新およびチェックすることができます。 |
完全な PSO | グラフィック API によって使用されるランタイムに必要な完全な PSO 状態。 これは最初 PSO と同じですが、追加のレンダー ターゲット情報が含まれています。 |
各グループで、次のパラメータがトラックされます。
| パラメータ | 説明 |
|---|---|
Missed | 事前キャッシュされていませんが、描画またはディスパッチの際に必要になるため事前キャッシュされるはずだった PSO の数。 原因として、誤りがあるシェーダー、レンダー ターゲットの状態、頂点属性、レンダー ターゲット情報が考えられます。 |
Untracked | 事前キャッシュが有効になっていない PSO の数。 原因として、無効にされた検証、グローバル マテリアル、サポートされていない頂点ファクトリ、サポートされていないメッシュ パス プロセッサ タイプが考えられます。 シッピング ビルドでは、特定のデバッグ情報が利用できない場合に、未追跡の PSO が代わりに欠落しているものとして表示されます。 |
ヒット | 正常に事前キャッシュされ、ランタイム時に使用される PSO の数。 |
Too late | 事前キャッシュ用にキューに入っていたが、必要なタイミングまでにコンパイルされなかった PSO の数。 |
Used | ランタイム時に使用される PSO の数 (上記すべての合計)。 |
Precached | 事前キャッシュされた (ただし、必ずしも使用されるとは限らない) PSO の数。 |
シェーダー パイプライン キャッシュは、PSO コンパイル自体によって発生した実際のランタイムヒッチの検出数に関する情報も提供します。 PSO コンパイルは、ランタイム PSO のコンパイルがある一定のミリ秒数よりも長くかかった場合にヒッチとしてマークされます。 デフォルトのしきい値は 20 ミリ秒です。 この値は r.PSO.RuntimeCreationHitchThreshold で変更できますが、できる限り小さい値に保つことを推奨します。
最初のドライバ キャッシュの実行は時間が長くなる可能性があるため、デフォルト値は 20 ミリ秒と高くなっています。
PSO 事前キャッシュに関する情報を収集する
ログ ファイル、Visual Studio デバッガー、Unreal Insights を使用することで、PSO プリキャッシュに関する詳細情報を取得し、一部の PSO がランタイム中にヒッチを発生させる理由を調査できます。 PSO の正しいプリキャッシュ状態は、PSO 検証が有効な場合にのみ、ログおよび Insights に表示されます(詳細は上記の「検証とトラッキング」を参照)。
PSO のミスまたは遅延が検出されると、UE は以下の情報をログに出力します。
PSO PRECACHING MISS:
Type: FullPSO
PSOPrecachingState: Missed
Material: M_AdvancedSkyDome
VertexFactoryType: FLocalVertexFactory
MDCStatsCategory: StaticMeshComponent
MeshPassName: SkyPass
Shader Hashes:
VertexShader: EC68796503F829FDEACC56B913C4CA86C6AD3C16
PixelShader: 651BF1ABBAEC0B74C8D2A5E917702A00EF29817B
Insights は、PSO プリキャッシュをデバッグするのに便利なツールです。 ゲームのフレーム状態シリーズにタイマー PSOPrecache: Missed と PSOPrecache: Too Late を追加すると、一定期間に発生した PSO コンパイルによるすべてのヒッチを簡単に把握できます。 下のスクリーンショットでは、PSO プリキャッシュのミスによる 5〜10 ミリ秒の小さなヒッチがいくつかあり、さらに 117 ミリ秒の大きなヒッチもあり、プレイヤーに認識されます。 それ以外の大きなヒッチは、PSO コンパイルが原因ではありません。
画像をクリックすると、拡大表示されます。
ズームインすると、これは透過処理パスから来ていることがわかります (詳細はログに記録されているはずです)。
画像をクリックすると、拡大表示されます。
詳細情報は、グローバル PSO 検証ヘルパー オブジェクトを参照してください。 検証を完全なトラッキング (r.PSOPrecache.Validation=2) に設定すると、メッシュパス プロセッサおよび頂点ファクトリタイプごとに数値がグループ化され、特定のミスの原因を追跡するのに役立ちます。 これにより、すべてのプリキャッシュ済み PSO の発生元を明確に把握でき、また過剰にシェーダーをプリキャッシュしている外れ値の特定にも役立ちます。
これらのパスごと、および頂点ごとのファクトリ統計情報は直接公開されませんが、それらを収集するデータ構造体を移動することによってデバッグ中に検査することができます。 これらはPSOPrecacheValidation.cppにあります。
FullPSOPrecacheStatsCollectorShadersOnlyPSOPrecacheStatsCollectorMinimalPSOPrecacheStatsCollector
次のスクリーンショットに例を示します。
画像をクリックすると、拡大表示されます。
エンジン機能で PSO 事前キャッシュを拡張
このセクションでは、PSO 事前キャッシュ用のサポート オブジェクトを拡張する方法について説明します。
UPrimitiveComponent
UPrimitiveComponent は、PSO 初期化に必要なすべての情報を収集します。 必要なのは、マテリアル インスタンス、頂点ファクトリ (必要に応じて頂点要素セットを含む)、および最終的なシェーダやレンダリング状態に影響する可能性のあるパラメータ セットで、これらは FMeshPassProcessor で使用されます。
パラメータは FPSOPrecacheParams に格納され、正しいデフォルト値は UPrimitiveComponent::SetupPrecachePSOParams で設定されます。
PSO 事前キャッシュ用のベース エントリ関数は次のとおりです。
/** Precache all PSOs which can be used by the primitive component */
ENGINE_API virtual void PrecachePSOs();多くの場合、派生コンポーネントはこの関数を実装する必要はなく、単純に事前キャッシュ用のパラメータ収集関数をオーバーライドするだけで済みます。
/**
* Collect all the data required for PSO precaching
*/
struct FComponentPSOPrecacheParams
{
EPSOPrecachePriority Priority = EPSOPrecachePriority::Medium;
完全な例は UStaticMeshComponent::CollectPSOPrecacheData にあり、よりシンプルなユースケースは WaterMeshComponent::CollectPSOPrecacheData で確認できます。
FVertexFactory
新しい頂点ファクトリには、頂点ファクトリ宣言マクロ IMPLEMENT_VERTEX_FACTORY_TYPE を用いて、EVertexFactoryFlags::SupportsPSOPrecaching フラグを設定し、PSO 事前キャッシュをサポートする必要があります。
次に、頂点ファクトリには次の関数を実装する必要があります。
static void GetPSOPrecacheVertexFetchElements(EVertexInputStreamType VertexInputStreamType, FVertexDeclarationElementList& Elements);明示的な頂点要素セットが指定されていない場合、PSO 事前キャッシュ中に FVertexFactory::GetPSOPrecacheVertexFetchElements が使用されます。
固定された頂点要素セットは、頂点ファクトリに EVertexFactoryFlags::SupportsManualVertexFetch フラグが設定されている場合、またはシェーダーで固定頂点要素セットを使用している場合に有効です。
頂点要素リストがメッシュの頂点バッファ データに依存している場合は、正しいセットを FPSOPrecacheVertexFactoryData で提供する必要があります。 これは UPrimitiveComponent::CollectPSOPrecacheData 実行時に行われます。 例としては、UStaticMeshComponent::CollectPSOPrecacheData と FLocalVertexFactory::GetVertexElements を参照してください。
FMeshPassProcessor
メッシュ パス プロセッサでは、指定された FPSOPrecacheParams を使用して特定のマテリアルを描画する際に使用可能なすべての PSO を収集するため、次の関数を実装する必要があります。
virtual void CollectPSOInitializers(const FSceneTexturesConfig& SceneTexturesConfig, const FMaterial& Material, const FPSOPrecacheVertexFactoryData& VertexFactoryData, const FPSOPrecacheParams& PreCacheParams, TArray<FPSOPrecacheData>& PSOInitializers) override {}ロジックは AddMeshBatch とほぼ同じです(理想的には部分的に共有可能です)。ただし、AddMeshBatch は MeshDrawCommand のビルド時に呼び出されますが、PSO 事前キャッシュ システムではコンポーネントの PostLoad 時に、より早く情報を収集しようとします。
シンプルな例は、FDistortionMeshProcessor::CollectPSOInitializers を参照してください。より包括的な例は、FBasePassMeshProcessor::CollectPSOInitializers を参照してください。
IPSOCollector
すべてのマテリアル シェーダーがメッシュ パス プロセッサを通過するわけではなく、EMeshPass::型 が定義されているわけでもありません (髪、Nanite、レイトレーシングの動的ジオメトリ更新など)。 これらの場合は、代わりにベース インターフェースから直接派生させる必要がある場合があります。
IPSOCollector には、実装が必要な単一の仮想関数があります。
// Collect all PSO for given material, vertex factory & params
virtual void CollectPSOInitializers(const FSceneTexturesConfig& SceneTexturesConfig, const FMaterial& Material, const FPSOPrecacheVertexFactoryData& VertexFactoryData, const FPSOPrecacheParams& PreCacheParams, TArray<FPSOPrecacheData>& PSOInitializers) = 0;PSO コレクターは、グローバル FRegisterPSOCollectorCreateFunction を介して作成登録する必要があります。 エンジンには、 FTranslucentLightingMaterialPSOCollector 、 FRayTracingDynamicGeometryPSOCollector など、 シンプルな例がいくつかあります。
GlobalPSOCollector
このページで前述したように、いくつかのグローバル グラフィック PSO は、起動時にすでに事前キャッシュされており、ランタイムの順列をコンパイルできることが確認されています。 この場合は GlobalPSOCollector が使用されます。 これは、IPSOCollector の簡易バージョンです。 グローバル FRegisterGlobalPSCollectorFunction オブジェクトを宣言する必要があります。これにより、グローバル PSO コレクター関数が提供されます。
typedef void (*GlobalPSOCollectorFunction)(const FSceneTexturesConfig& SceneTexturesConfig, int32 GlobalPSOCollectorIndex, TArray<FPSOPrecacheData>& PSOInitializers);使用例については、「DeferredLightGlobalPSCollector」または「RegisterVolumetricFogGlobalPSOColector」を参照してください。
PSO 事前キャッシュのミスをデバッグする
上記の PSO 事前キャッシュのミスの原因をデバッグするには、Visual Studio で手動のデバッグを使用する必要があります。
最小限の PSO 状態でのミスのデバッグは容易です。これらは描画時ではなく、MeshDrawCommand の構築時にトリガーされるためです。 完全な PSO の計算に必要な最終レンダー ターゲット情報は描画中にしか利用できないため、デバッグが難しくなります。
関数 LogPSOMissInfo は、ランタイムでミスが発生した際にデバッガを停止させる便利な場所です。 コールスタックやウォッチウィンドウから、使用されているマテリアル、レンダリングパス、頂点ファクトリ、および FPrimitiveSceneProxy に関する追加情報を取得できます。 また、ComponentForDebuggingOnly メンバーを使用することで、UPrimitiveComponent に関する情報も取得できます。 これらのデータの多くは、ミスが検出された際に (この関数で収集されて) ログファイルに出力されます。
ただし、LogPSOMissInfo が実行される時点では、通常そのコンポーネントで PSO 事前キャッシュはすでに行われています。 そのコンポーネントの PSO の事前キャッシュ中に不正なシェーダーやレンダリング状態が使用されている理由を探ろうとする場合、そのコンポーネントや指定されたパスのマテリアルの PSO 事前キャッシュ中にブレークポイントを追加する必要があります。
r.PSOPrecache.BreakOnMaterialName は、指定した名前の マテリアル が見つかった場合に PSO 事前キャッシュ中にブレークするのに役立ちます。ランタイム 状態と比較したときに、特定の レンダリング 状態が異なる理由を突き止めるのに役立ちます。 r.PSOPrecache.BreakOnPassName と r.PSOPrecache.BreakOnShaderHash を使用して、問題のある PSO を絞り込むこともできます。 この情報は、上述のようにログに表示されます。
r.PSOPrecache.UseBackgroundThreadForCollection は、PSO初期化のためのコレクション処理のバックグラウンド スレッド タスクを無効にするのに役立ちます。これにより、PSO 事前キャッシュのミスのデバッグ中にコンポーネント情報やその他の状態の追跡が容易になります。
また、FPSOPrecacheParams の値も場合によってはチェックする必要があります。これらは、PSO で使用されるシェーダーやレンダリング状態に影響する可能性があるためです。