Large World Coordinates (LWC) レンダリングの概要

Large World Coordinates のレンダリングの概要。

LWC レンダリングの概要

ラージ ワールド座標とともに新しい HLSL タイプが導入されました。これは「LargeWorldCoordinates.ush」ファイルに含まれています

HLSL タイプ

メモ

FLWCScalar FLWCVector2/3/4

これらは float1/2/3/4 に似たタイプですが、追加の Tile 座標が含まれます。そのため、FLWCVector2 は float2 Tile と float2 Offset で構成されます。表される値は Tile * TileSize + Offset の式で算出されます (TileSize は 256k として定義された定数値)。

FLWCMatrix FLWCInverseMatrix

これらは float4x4 に似たタイプですが、これらの両方には追加の float3 Tile 座標が含まれます。

FLWCMatrix

マトリックスの乗算後に、Tile 座標を結果に追加します。

FLWCInverseMatrix

マトリックスの乗算前に Tile 座標を追加します。

FLWCMatrix

ワールド空間へのトランスフォーム (LocalToWorld) に使用します。

FLWCInverseMatrix

ワールド空間からのトランスフォーム (WorldToLocal) に使用します。

これらのタイプでは LWCAddLWCRsqrt などの演算を実行できます。LWC 入力値を受け取る演算では LWC 出力 (LWCAdd) が返され、その他の演算では通常の浮動小数出力 (LWCRsqrt) が返されます。この違いは選択した実装方法によるものですが、座標をより小さくする演算では通常の浮動小数値に戻されます。

シェーダー コードでは、すでに多くのタイプが LWC バリアントに切り替わっています。次にいくつかの主な例を示します。

  • 大まかには、LWC タイプはユニフォーム バッファ内には直接含まれていません。エンティティには、同じ Tile 座標 (WorldToLocal、LocalToWorld、AbsoluteWorldPosition) を使用できるいくつかのデータが含まれているため、通常のパターンでは、通常の非 LWC 値は、単一の float3 TilePosition 値とともにユニフォーム バッファ (RelativeWorldToLocal、LocalToRelativeWorld、RelativeWorldPosition) に格納されます。

シェーダー内部では、このユニフォーム データが新しい構造体タイプに「アンパック」されます。この構造体タイプには、単一の TilePosition で初期化される多くの値を持つ実際の LWC 値が含まれます。

  • SceneData.ush、FPrimitiveSceneData、FInstanceSceneData には、更新されたさまざまなメトリックと位置ベクターが含まれます。

  • グローバル カメラ ユニフォームでは、(PreViewTranslation など) さまざまなメトリックスとオフセットが変更されました。以前は、(インスタンス化されたステレオ レンダリングを処理する) メッシュのレンダリング時には ResolvedView を介して、ポストプロセスと他のグローバル パスのレンダリング時には View を介して、グローバル カメラ ユニフォームにアクセスしていました。

エンジンの以前のバージョンでは、View はグローバル ユニフォーム バッファを直接参照しており、その結果として、アンパックされたグローバル View 構造体を参照する新しいエイリアス「PrimaryView」が追加されました。そのため、View.PreViewTranslation などの名前が PrimaryView.PreViewTranslation に変更されます。ResolvedView.PreViewTranslation は適切な場合に引き続き機能し、通常の View エイリアスからの非 LWC の数値へのアクセスに使用できます。

  • FNaniteView がカメラ ユニフォームに対する更新に一致するようになりました。

  • ライトの位置および反射キャプチャの位置は、新しい LWC HLSL タイプに切り替わりました。

これらのグローバル タイプを切り替えることで、LWC をサポートするためにシェーダー コードをリファクタリングする必要のある個所を全般的に示すことができます。次に例を示します。

    float3 WorldPosition = mul(Input.LocalPosition, View.LocalToWorld);

    //This will no longer compile, and will need to be refactored to:

    FLWCVector3 WorldPosition = LWCMultiply(Input.LocalPosition, PrimaryView.LocalToWorld);

最初の LWC パスでは、すべてのシェーダーが LWC と適切に機能することは確認されません。

これらに対応するには、グローバル関数 LWCHackToFloat を使って LWC タイプを非 LWC タイプに変換できます。

LWCHackToFloatLWCToFloat 関数のラッパーとして機能します。これらの違いは、LWC スケールでの変換が安全とわかっている場合に使用される LWCToFloat 関数です。LWCHackToFloat は検索可能なマーカーです。WorldPositionfloat3 から FLWCVector3 に切り替えた際にコードベースをリファクタリングする時間がなかった場合は、次のコードを代わりに使用できます。

    float3 WorldPosition = mul(Input.LocalPosition, LWCHackToFloat(PrimaryView.LocalToWorld));

TranslatedWorldSpace は、UE5 シェーダーで使用されている既存のエンジン コンセプトです。以前は、カメラの原点に相対することで精度を高める意図がありましたが、TranslatedWorldSpace での作業時には浮動小数値を安全に使用できるため、この動作は LWC にも有用です。WorldPosition を LWC 値に変換するのではなく、次のような数式を使用できます。

    float3 TranslatedWorldPosition = mul(Input.LocalPosition, PrimaryView.LocalToTranslatedWorld);

クイック移植ガイド

既存の HLSL コードベースを Unreal Engine 5 に移植できます。次は、適切に変換を行うための推奨事項です。

  • ワールド空間内の値/メトリックスにアクセスする際に ViewPrimaryView に変更する (LocalToWorld、PreViewTranslation)。

  • ワールド空間内で実行するコードがコンパイルされず (関数オーバーライドまたはタイプ変換の不足)、コードベースをリファクタリングするための労力がない場合は、必要に応じて LWCHackToFloat を使用する。例:

    (LWCHackToFloat(PrimaryView.PreViewTranslation))

それでもコードがコンパイルされない場合:

  • WorldSpace の代わりに TranslatedWorldSpace で機能するようシェーダー コードを変更することを検討してください。

  • ワールド空間の値は LWC タイプ (float3 ではなく FLWCVector3) である必要があるため、LWCAddLWCMin 関数を使用する必要がある場合があります。

新しいコードを開発する際は上記のガイドラインに従って、可能な場合は TranslatedWorldSpace を使用してください。そうでない場合は LWC タイプを使用することを推奨します。

マテリアル トランスレータ

マテリアル トランスレータ は、LWC 値に対応するように更新されました。マテリアル ノードでは、AbsoluteWorldPosition へのクエリ時と WorldSpace へのトランスフォーム時に、浮動小数値ではなく LWC 値を出力します。

マテリアルは LWC スケールで機能しますが、追加のパフォーマンス コストが生じる場合もあります。 LWC 演算ではより多くのプロセス呼び出しが発生するため、移植するマテリアルがより高負荷になる可能性があります。

タグ