4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

カバー株式会社Advent Calendar 2024

Day 15

UEのポストプロセス上でUVと深度からワールド位置を求める

Last updated at Posted at 2024-12-14

ちょっとした小ネタです。

UE上でポストエフェクトを書いていると、近隣のピクセルのワールド位置が欲しくなる事があるのではないでしょうか。
しかしながらWorldPositionノードではUVが指定できないので取得したいピクセルを自由に選ぶ事ができません。

今回はその取得方法を解説します

参考になるコード

実はすでにUEのエンジン内には目当ての処理を実装している箇所があります。
下記の場所にあるLumenPosition.ushです。

Engine\Shaders\Private\Lumen\LumenPosition.ush

この中のGetWorldPositionFromScreenUVが参考にし易いので、こちらの手法を実際に使ってみましょう。

float3 GetWorldPositionFromScreenUV(float2 ScreenUV, float SceneDepth)
{
	float2 ScreenPosition = (ScreenUV - View.ScreenPositionScaleBias.wz) / View.ScreenPositionScaleBias.xy;
	float3 WorldPosition = mul(float4(GetScreenPositionForProjectionType(ScreenPosition, SceneDepth), SceneDepth, 1), DFHackToFloat(PrimaryView.ScreenToWorld)).xyz;
	return WorldPosition;
}

使ってみる

ではまず、取得したワールド位置から距離を見て適当な濃淡をつけてみる事でWorldPositionと同等の性能がある事を確認します。

テスト用に下記BPを組みました。
SphereMaskを使い、原点から半径4mをマスクします。
ワールド位置を取得する処理はカスタムノードを使っての実装となります。
image.png

カスタムノード内で書いたUVと深度からワールド位置を取得するコード

    float2 uv = ClampSceneTextureUV(ViewportUVToSceneTextureUV(DERIV_BASE_VALUE(inUV), 1), 1);
    float3 depth = SceneTextureLookup(uv, 1, false).rgb;
    float2 screen =  (uv - View.ScreenPositionScaleBias.wz) / View.ScreenPositionScaleBias.xy;
    float3 wp = mul(float4(GetScreenPositionForProjectionType(screen, depth.x), depth.x, 1),  DFHackToFloat(PrimaryView.ScreenToWorld)).xyz;
	return wp;

気を付ける所として、指定するUVは表示されいてる領域を0-1に正規化したものでは無く実際のUVです。
したがって、ClampSceneTextureUVとViewportUVToSceneTextureUVを使って補正を掛ける必要があります。

結果

意図した結果を得る事が出来ました。
image.png

どういった場面で使うか

実際での使いどころの一例として、上記のマスクを標準のDOFではない、自前のDOFのフォーカス範囲の判定に使ってみました。
image.png

ブラー時、サンプリング毎にワールド位置を取得する事でフォーカス範囲を判定しています。
標準DOFの後のパスでAfterDOFとして書かれた半透明にかぶせる為の機能として使ったりします。

最後に

定期的に使う必要出てくる機能です。都度やり方を調べる事が多いので自分のメモの意味も込めて書きました。
同じ事を調べていたどなたかの役に立てば幸いです。

注意点

今回はエンジン内部のコードを参考にしましたが、更新のタイミングで定義が変わったりする事があります。
実際に5.3→5.4の更新の際はLWCHackToFloatがDFHackToFloatに代わりました。
バージョンを上げる際はその辺り注意して追うようにしてください。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?