Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

【CEDEC2025】『鉄拳8』Unreal Engine 5 Niagaraによる開発事例と...

【CEDEC2025】『鉄拳8』Unreal Engine 5 Niagaraによる開発事例と最適化 ~60FPSを守る~

「鉄拳8」VFX開発におけるNiagaraモジュールの実装事例と
膨大なアセットを扱いながら60FPSを維持するためのNiagaraの最適化事例について紹介します。

Niagaraを使って実現可能な表現や、モジュールを拡張実装した具体的な実装例も紹介します。
その中で、60FPSを下回らないためにNiagaraで行った最適化についても紹介します。

※本セッションはUnrealEngine5.2 を利用した事例になります。

Avatar for Bandai Namco Studios Inc.

Bandai Namco Studios Inc. PRO

December 22, 2025
Tweet

More Decks by Bandai Namco Studios Inc.

Transcript

  1. リアルタイム破壊表現を物理破壊プラグインを使わずNiagaraで表現した方法 イマイチ… プラグインの検証 APEX Chaos 5.0EA 4.27 4.26 β版 非推奨

    5.0~ 不安定? APEX Chaos その他 ? 当初の開発環境は、Unreal Engine 4.27~5.0(EA)の間で、リアルタイム破壊をどのプラグインを利用するか 検討していました。 どれかを選定する必要がありましたが、検証の結果どちらも将来的に不安定であることが判明しました。 ・Apex Destruction →UE5.0以降はサポート対象外 ・Chaos Destruction →β版で負荷が高く、さまざまなアセットの置き換えが必要
  2. リアルタイム破壊表現を物理破壊プラグインを使わずNiagaraで表現した方法 HoudiniのFractureノードを使用して、事前にモデルを分割し、破片1つをそれぞれのフレームへ原点配置します。 その後、改造したFluidのVATノードを利用して、各種データを書き出します。 - U: 各種頂点の情報 - V: 破片のIDとして利用(通常はアニメーションフレーム) Niagara

    ROP より、HCSV(hjson)に各破片ごとに次の情報が書き出されています。 - 破片ID / 位置 / 質量 / コリジョン形状 など 破壊Niagaraのデータ構造 分割 原点に集める 破片の中心座標とID 破片をアニメーションフレームに割り振り (ID+座標)+(コリジョン形状+質量)をマージして破片ごとに設定 頂点情報 破 片 ID UV 破 片 ID 断面UVマスク 破 片 ID
  3. ゲームスピードに応じたパーティクルの制御 Delta TimeをInputに出して変更できるように改造 Particle側でDelta Timeを利用しているモジュールにも適応 モジュール紹介 Niagara Parameter Collectionに設定したゲームスピード(0.0~1.0)を使って2パターン出力できるよう設計してい ます。

    1. NiagaraのDelta Timeの変動値をゲームスピードで相殺し、スローを無視した通常速度のDelta Timeを生成。 2. NiagaraのDelta Timeの変動値をゲームスピードで相殺し、任意の範囲でClampした速度のDelta Timeを生成。
  4. メッシュ空間の1軸を固定するメッシュビルボード表現 NiagaraMeshRendererProperties.h enum class ENiagaraMeshLockedAxisSpace ~~ Local_Mesh_X, // X軸固定 Local_Mesh_Y,

    // Y軸固定 Local_Mesh_Z, // Z軸固定 NiagaraMeshParticleUtils.ush #define PARTICLE_SPACE_MESH_LOCAL_X 3 ~~ NiagaraMeshParticleSRTParams Params.LockedAxisSpace if (Params.LockedAxisSpace == PARTICLE_SPACE_MESH_LOCAL_X)など Niagaraのエンジン改造部分の紹介をします。EnumとShaderの構造体の関係性です。 エンジンコードはDefineの値とEnumの値を比較しているので、以下のコードを拡張しています。 実装紹介
  5. メッシュ空間の1軸を固定するメッシュビルボード表現 NiagaraMeshParticleUtils.ush float3x3 NiagaraGetMeshFacingMatrix(FLWCVector3 ParticleSimPosition, NiagaraMeshParticleSRTParams Params, float4 rotation) Const

    float4 rot = normalize(rotation); ~~ 式省略 ~~ 以下3つはParams.LockedAxisSpaceで分岐する LockedAxis = float3((1.0f - (yy + zz)), (xy + wz), (xz - wy)); // X軸固定 LockedAxis = float3((xy - wz), (1.0f - (xx + zz)), (yz + wx)); // Y軸固定 LockedAxis = float3((xz + wy), (yz - wx), (1.0f - (xx + yy))); // Z軸固定 ~~ LockedAxis = NiagaraWorldToLocalVec(LockedAxis, Params);// 通常 NiagaraMeshParticleSRT NiagaraCalculateMeshParticleSRT(NiagaraMeshParticleSRTParams Params) if (Params.LockedAxisSpace == PARTICLE_SPACE_MESH_LOCAL_X ~~) SRT.Rotation = mul(FacingMat, NiagaraQuatTo3x3(Params.MeshRotation));// メッシュ軸固定の場合 else SRT.Rotation = mul(SRT.Rotation, FacingMat); // 通常 Enumで追加された分岐とメッシュの回転情報はShaderで計算しています。 LockedAxisでシステムの回転情報を渡している箇所の条件を分岐させてメッシュの回転情報を渡すように変更しました。 Rotation→Vectorに変換するモジュールと同じ計算 実装紹介
  6. 実際に導入しているNiagaraの最適化手法 PSOCacheのみだとヒッチに対する効果が少々不足していたため、PSOPreCacheを併用して実装しています。 PSOCache Niagaraのみ発生するレベルを作成してPSOを収集しています。その後、PSOを変換してパッケージに含め、 起動時にコンパイルを実行しています。 PSOPreCache UPrimitiveComponent を対象に、PostLoad の実行中にPSOを事前にキャッシュします。 UE5.3以降は更に機能が向上しています。

    PSOCache r.PSOPrecache.ProxyCreationWhenPSOReady →描画がかなり遅延するのでオフにしています。 fx.Niagara.Emitter.ComputePSOPrecacheMode →Emitterが完了するまで描画を待ちます。動作優先 ▪PSOPreCache実装例 参考:The Matrix Awakens: An Unreal Engine 5 Experience WindowsEngine.ini r.PSOPrecaching=1 r.PSOPrecache.Resources=1 r.SkipDrawOnPSOPreCaching=0 r.PSOPrecache.ProxyCreationWhenPSOReady=0 r.pso.PrecompileThreadPoolPercentOfHardwareThreads=7 5 r.PSOPrecache.GlobalComputeShaders=1 r.ShaderPipelineCache.BatchSize=35 r.ShaderPipelineCache.BatchTime=14.0f fx.Niagara.Emitter.ComputePSOPrecacheMode=3 Niagaraを発生させてPSOCacheを収集するレベル
  7. その他Niagaraの最適化項目 最適化においての確認環境の重要性 キャラクターやステージの切り替え、モーション再生など、開発初期では負荷確認に多くの時間とコストがかかって いました。 そこで、事前に一定の最適化とレギュレーションを適応できるよう、エフェクトの単体確認環境を用意しています。 エフェクト実装 ROM確認 アセット確認 最適化FIX 開発初期

    負荷計測 最適化 レギュレーション確認 NG OK アセットを検索・確認 エディタでゲーム確認 VFX班へ修正依頼 GPUProfilerで計測 アセットと原因の特定 エフェクト実装 最適化FIX 確認環境実装後 ROM確認 負荷計測 アセット単体確認 最適化 レギュレーション確認 NG OK GPUProfilerで計測しな くても、基準値内かどう かある程度判別可能に! アセットをツールで確認 VFX班へ修正依頼 COST