Unreal Engine 全体で Large World Coordinate が実装されました。メイン エンジンでの実装については、「Large World Coordinate」ページを参照してください。簡単に説明すると、データ型 FVector が float
ではなく double
になりました。
Niagara での実装は、メイン エンジンの実装とは異なります。CPU でも GPU でも効率的に計算を行う必要があるため、CPU と GPU の両方を使用した作業に制約があります。代わりに、Niagara では新しい方法で位置データを格納します。
十分に大規模なワールドは、タイルのグリッドに分割されます。空間での 1 つの位置について考えると、位置にはタイル単位内の独自の相対的な位置と、ワールドでのそのタイルの位置を持ちます。この具体的な内容を概念的に表した次の図を参照してください。
画像をクリックするとフルサイズで表示されます。
これまで、Niagara の位置はベクターと互換性があり、ワールド基点からの方向と距離として定義されていました。現在、情報を意味のあるものにするためには、エミッタが位置しているタイルを基準としてエミッタの位置を特定するためには追加データが必要になりました。
UE5 では、原点を基準とした位置だけでなく、システムがどのタイルに位置しているかという情報も保存するために、新しいデータ形式が必要です。こうすることで、他のタイプのベクター、およびこの追加データを保持している位置を区別することができます。
UE4 および UE5 の位置データ
UE4 と UE5 の主な違いは、パーティクルの位置データの格納方法、つまり、Particles.Position
です。
UE4 | UE5 | |
---|---|---|
Particles.Position type | ベクター | 位置 |
Local space emitter | Particles.Position は、ゲームにおける Niagara システムの原点を基準とします |
Particles.Position は、ゲームにおける Niagara システムの原点を基準とします (変更されない) |
World space emitter | Particles.Position は、ゲームの原点 (0,0,0) を基準とします |
これが有効である場合、 Particles.Position は、システムの位置を基準とします。小さな座標の場合、これは引き続きゲームの原点です。比較的大きな座標の場合、任意の数値である可能性があります。 |
Niagara で Large World Coordinate を有効または無効にする方法
プロジェクトの Large World Coordinate
新規プロジェクトでは、Large World Coordinate がデフォルトでオンになっています。UE5 でプロジェクトを開くと、プロジェクトが自動的に変換されます。
プロジェクトがそれほど大規模でなく、Large World Coordinate をサポートする必要がない場合は、[Edit (編集)] > [Project Settings (プロジェクト設定)] で完全にオフにすることができます。[Plugins] > [Niagara] で、[System Support Large World Coordinates (システムで Large World Coordinate をサポートする)] 設定を確認し、プロジェクトでこの設定をオフにします。
画像をクリックするとフルサイズで表示されます。
システムの Large World Coordinate
プロジェクトで Large World Coordinate を有効にする必要があるものの、特定の個々のシステムでは無効にしたい場合があります。この場合、Niagara エディタで Niagara システムを編集することができます。[System Properties (システム プロパティ)] の [Rendering (レンダリング)] セクションで [Support Large World Coordinates (Large World Coordinate のサポート)] を無効化することができます。
画像をクリックするとフルサイズで表示されます。
Niagara で Large World Coordinate をテストする方法
プロジェクト ファイルを UE4 から UE5 に初めてアップデートするときや、システムのテストを開始するときは、Niagara システムが Large World Coordinate で適切に動作すること検証することをお勧めします。Niagara システムが Large World Coordinate で機能するかどうかをテストするには、最初のタイルの外側に Niagara システムを移動する必要があります。これを実行するには、以下に概説するように、複数の方法があります。
エフェクトを非常に遠くに移動させる
エフェクトを原点から非常に離れた位置に移動させてから、エフェクトを再生して、動作を検証することができます。これは、エンジン コード自体に変更を加えることなくテストする唯一の方法です。たとえば、システムを原点から 3000000 単位移動させると、元のタイルの外側のタイルにシステムが配置されます。
タイル サイズの定数を変更する
また、Large World Coordinate タイルのタイル サイズは、定数定義で変更することができます。Engine/Source/Runtime/Core/Private/Misc/LargeWorldRenderPosition.cpp
で、10 単位など、UE_LWC_RENDER_TILE_SIZE
を非常に小さい値に変更します。これで、エフェクトをレベルに配置すると、原点から 10 単位以上離れていれば、エフェクトは新しいタイル内に位置します。
既存のプロジェクトを更新する
HLSL での Particles.Position
プロジェクト用に HLSL でカスタム スクリプトを書いた場合は、Large World Coordinate で動作するようにこれらのカスタム スクリプトを更新する必要があります。以前のバージョンでは、HLSL を使用して Particles.Position
を直接固定値に設定している可能性がありますが、これはLarge World Coordinate では動作しません。
代わりに、そのアセットの Large World Coordinate のサポートを無効にするか、ワールド空間ベクターを位置に変換することができます。
画像をクリックするとフルサイズで表示されます。
どのタイルに位置しているかを把握する必要がある場合、これは Engine.Owner.LWCTile
に格納されます。
カスタム モジュール
Niagara スクリプト エディタ や スクラッチパッド を使用すると、独自のカスタム モジュールを作成できます。前のバージョンですでにカスタム モジュールを作成している場合は、Large World Coordinate を使用するプロジェクトに変換すると、暗黙的に動作しないことがあります。
動作しない原因は、タイル情報を含む位置データと、タイル情報を含まない法線ベクターの違うことです。Particles.Position
などのコア パラメータは position
型に自動的に変換されますが、そのようなパラメータに接続されているカスタム ベクター入力は変換されません。
次の例では、Box Origin がデフォルトのバインディングとして Particles.Position
を使用しています。ただし、それ自体は position
型ではありません。
画像をクリックするとフルサイズで表示されます。
後方互換性を維持するために、既存の接続は維持され、位置の型は法線ベクター型に変換されます。
既存のベクター入力の型を変更する
Niagara スクリプトでは、既存のモジュールがある場合、いくつかのパラメータを position
型に更新することをお勧めします。既存のベクター入力または出力の型を position 型に変更するには、次の手順を実行します。
-
Niagara スクリプト エディタ でモジュール スクリプトを開きます。
-
[Parameter (パラメータ)] タブで、型を変更したいパラメータを右クリックします。
-
コンテキスト メニューで [Change Type (型を変更)] > [Position (位置)] を選択します。
画像をクリックするとフルサイズで表示されます。
パラメータを position 型に変更し、そのパラメータが異なる型のパラメータに接続されている場合、孤立したピン接続が作成されます。この方法によって、次に実行する内容つまり、他のパラメータの型も変更するか、またはデータを別の型に変換するかを決定することができます。
このスクリプトが所有するパラメータのみを変更することができます。外部からパラメータを継承している場合、そのパラメータはロックされており、型を変更できないことがわかります。
ノード グラフのベクターと位置を変換する
ノード グラフで vector
と position
を接続すると、このシステムは変換ノードにPosition ->Vector または Vector ->Position を追加します。ただし、この場合、原点タイルの外側で行われる Large World 変換は考慮されることなく、値がコピーされることに注意してください。これにより、重要な情報が失われる場合があります。
画像をクリックするとフルサイズで表示されます。
position 型をワールド空間ベクターに変換する必要がある場合は、関数 Position to Vector を使用します。反対に、ワールドスペース ベクターを位置に変換するには、Vector to Position を使用できます。
画像をクリックするとフルサイズで表示されます。
位置からベクターへの変換、またはその逆の変換を行う場合は、常にデータの損失が発生する可能性があります。そのため、精度が低下したり、原点タイル外で予期しない動作が発生することがあります。念のため、最初から最後まで、位置は変換しないで使用してください。ワールド空間への変換は、データ インターフェースまたはレンダラでのみ実行することが理想的です。
パーティクル データ インターフェースをエクスポートする
Export Particle データ インターフェースを使用すると、位置データをブループリントに送信することができます。以前にすでにこれを使用していた場合は、Large World Coordinate 用にブループリントを更新する必要があります。
画像をクリックするとフルサイズで表示されます。
Receive Particle Data イベント ノードには、Simulation Position Offset というパラメータがあります。これには、自分が位置しているタイルのオフセット データが格納されます。これをスクリプトの最後にシミュレーション位置に追加することで、シミュレーション空間からワールド空間に再度変換することができます。
動的マテリアル パラメータ
位置データは、タイル オフセットに関する追加情報を保持しているため、この情報を保持していないベクターに直接リンクすることはできません。プロジェクトが、レンダラでそのマテリアルにバインドするダイナミック入力を使用して位置データをマテリアルにエクスポートするように設定されている場合、これはLarge World Coordinate では動作しません。この問題を解決するには、位置データをワールド空間ベクターに変換することができます。

ラージ座標の場合、どのタイルに位置しているかという追加のオフセット情報が失われるため、このことにより、ラージ座標ではオーバーフローが発生することがあります。
引き続き使用するマテリアル バインディングがある場合は、それを Engine.Owner.LWCTile
にリンクすることで、このオフセット情報を再び追加することができます。
画像をクリックするとフルサイズで表示されます。
マテリアル自体で、ConvertNiagaraPositionToWorldspace マテリアル関数を使用して、タイル オフセットをシミュレーション位置に追加することもできます。
画像をクリックするとフルサイズで表示されます。
カスタム データ インターフェース
ワールド スペース位置で動作する関数を含むカスタム データ インターフェースを作成した場合、これらを更新する必要があります。
必要に応じて、入出力用の FVector
ではなく FNiagaraPosition
型を使用するように既存の関数を置き換えます。UNiagaraDataInterface::UpgradeFunctionCall
をオーバーライドして、既存の関数の使用方法をアップグレードすることができます。
シミュレーションの位置を変換するために、システム インスタンスからヘルパー オブジェクトを取得することができます。
FNiagaraLWCConverter LWCConverter = SystemInstance->GetLWCConverter();
GPU データ インターフェース関数の場合、シェーダー コンテキストに供給された FNiagaraDataInterfaceArgs
からシステムのLarge World Coordinate タイルを取得することができます。この例を確認する必要がある場合は、カメラ データ インターフェースなどの既存の使用方法を確認することができます。
カスタム レンダラ
また、位置データを読み取るすべてのカスタム レンダラを更新する必要があります。データ インターフェースと同様に、システム インスタンスからコンバーターを取得することができます。唯一の違いは、localspace emitter をレンダリングしているかどうかも把握しておく必要があることです。
FNiagaraLWCConverter LwcConverter = SystemInstance->GetLWCConverter(bIsLocalSpaceEmitter);
読み取ったパーティクル位置は、以下を使用してワールド空間に変換することができます。
FVector WSPos = LwcConverter.ConvertSimulationPositionToWorld(SimPos);
すでに実装されている例については、既存の Niagara レンダラを確認してください。