Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Object Space Raymarching in Unreal Engine 5.2

がむ
September 01, 2023

Object Space Raymarching in Unreal Engine 5.2

がむ

September 01, 2023
Tweet

More Decks by がむ

Other Decks in Programming

Transcript

  1. 自己紹介
 @gam0022(がむ)/ Sho HOSODA
 グラフィックスエンジニア/Unityでモバイルゲームを開発
 『Unityバイブル R5夏号』 を執筆
 • ボーンデジタルの


    Unityバイブルシリーズの最新号 
 • 年2回の定期刊行の第1号 
 • ShaderGraphの章を担当
 • 2023-08-29発売
 2
  2. 自己紹介
 @gam0022(がむ)/ Sho HOSODA
 グラフィックスエンジニア/Unityでモバイルゲームを開発
 WORMHOLE by @gam0022 & @sadakkey

    
 1st place in Combined Demo Compo at Tokyo Demo Fest 2018 
 Made with Unity 
 RE: SIMULATED by @gam0022 & @sadakkey 
 1st place in PC 64K Intro at Revision 2020 
 Original WebGL Framework 
 Unityゲーム プログラミング・バイブル 2nd Generation 
 2021年 ボーンデジタル出版
 著者のひとりとして参加
 商業誌でレイマーチングを解説する実績を解禁 🏆
 5
  3. レイマーチングとは?
 float sdBox(vec3 p, vec3 b) { vec3 q =

    abs(p) - b; return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0); } https://iquilezles.org/articles/distfunctions/ 12
  4. レイマーチングとは?
 • レイマーチングを可視化したアニメーション by @kanetaaaaa 
 ‣ Raymarching in Raymarching

    
 ‣ https://twitter.com/kanetaaaaa/status/1141307706139004934 
 ‣ https://qiita.com/kaneta1992/items/21149c78159bd27e0860 
 13
  5. レイマーチングとは?
 • レイマーチングのアルゴリズム
 ‣ 距離関数だけレイを進めるのを繰り返す(マーチング・ループ)
 • 距離関数dが0に近似できたら衝突したと判定
 ‣ abs(d) <

    eps
 ‣ epsは0.001 など適切に設定
 • ループ回数がNを超えたら衝突していないと判定
 ‣ Nは100〜300くらいが一般的
 極めてシンプル
 14
  6. 実装の流れ
 1. UE上のHLSL(.ush)シェーダー開発環境の構築 
 a. C++の開発環境のセットアップ 
 b. AddShaderSourceDirectoryMappingでシェーダーを配置するディレクトリを登録 


    
 2. UE上のレイマーチングの実装 
 a. HLSL(.ush)でレイマーチングを実装 
 b. MaterialのCustomノードの Include File Paths に .ush を追加、 
 レイマーチングの関数を呼び出す 
 c. Customノードの計算結果をResultノードに出力、ライティング計算はエンジン側に任せる 
 19
  7. HLSL(.ush)によるシェーダー開発環境の構築
 • まずはC++の開発環境を整える必要がある 
 • Visual Studio 2022のセットアップ|Unreal Engine 5から始める

    C++ & Blueprint 
 • 上記の記事を参考にVisual Studio 2022と必要なコンポーネントをインストール 
 
 
 20
  8. HLSL(.ush)によるシェーダー開発環境の構築
 • C++の開発環境をセットアップしたら、AddShaderSourceDirectoryMappingを呼び出してシェーダーを配置するディレクトリをエ ンジン側に登録する
 
 • 下記の記事の「普通の方法」を参考にC++のコード実装
 • UE4,5 プロジェクトファイル内の外部シェーダーファイル(usf,

    ush, hlsl)をインクルードする為の設定。 - Qiita 
 • C++プロジェクト化
 • プロジェクト名.Build.csにRenderCoreへの依存関係を追加
 • プロジェクトにモジュール開始,終了ファンクションを追加
 • モジュール開始のStartupModule()に下記のコードを追加
 
 void FMyProjectModule::StartupModule() { UE_LOG(LogTemp, Warning, TEXT("Module Started")); FString ShaderDir = FPaths::Combine(FPaths::ProjectDir(), "Shaders"); AddShaderSourceDirectoryMapping("/Project", ShaderDir); } 21
  9. Material Editor全体
 • レイマーチングの処理はHLSLで実装
 ‣ ノードで実装するには複雑すぎる
 
 • ノード部分の実装内容は限定的
 ‣

    カメラのレイの生成
 ‣ Emissiveのパターン計算
 ‣ 前後関係の解消のためのPixel Depth Offsetの計算
 25
  10. 実装解説:レイマーチング基本
 Raymarching.ush では以下のインターフェースで関数定義 
 ノードの Additional Outpus に対応する値は inout を指定


    
 void raymarching( float3 origin, float3 ray, int raymarchingLoop, float uniformScale, float3 mengerOffst, float mengerScale, inout float hit, inout float depth, inout float3 hitPosition, inout float3 albedo, inout float3 normal, inout float ao, inout float emissive ) コード全体は長いので省略 26
  11. 実装解説:レイマーチング基本
 CustomノードのCodeでは、raymarhcingの関数を呼び出すだけ 
 
 albedo = objectAlbedo; raymarching( origin, ray,

    raymarchingLoop, uniformScale, mengerOffst, mengerScale, hit, depth, hitPosition, albedo, normal, ao, emissive ); return albedo; 27
  12. 実装解説:レイマーチング基本
 Raymarching.ush では以下のインターフェースで関数定義 
 ノードの Additional Outpus に対応する値は inout を指定


    
 void raymarching( float3 origin, float3 ray, int raymarchingLoop, float uniformScale, float3 mengerOffst, float mengerScale, inout float hit, inout float depth, inout float3 hitPosition, inout float3 albedo, inout float3 normal, inout float ao, inout float emissive ) コード全体は長いので省略 29
  13. 実装解説:レイマーチング基本
 • Material Domain: Surface
 ◦ レイマーチングはボリュームレダリングの印象があるかもしれないが、SurfaceでOK
 • Blend Mode:

    Masked
 ◦ レイマーチングの衝突判定によって形状をマスクする必要がある
 ◦ このオプションを有効にすることで、Opacity Maskを出力できる
 ▪ 交差している場合は1、交差していない場合は0を出力
 ▪ 要するにdiscard
 • Shading Model: Default Lit
 ◦ ライティング計算はエンジン側に任せる
 • Two Sideded: ON
 ◦ カメラがレイマーチングの内部に
 入った場合に両面描画が必要
 31
  14. Materialノード解説:カメラのレイの生成
 • ray(レイの方向)は簡単 
 ‣ ray = normalize(Surfaceの座標 - カメラの位置)


    ‣ ※Surfaceの座標 = 描画しようとしているピクセルのワールド座標 
 33 カメラの位置 Surfaceの座標 差分 正規化 レイの方向(ray)の生成
  15. もっと詳しい情報
 • GitHub
 ‣ UnrealEngineのプロジェクト
 ‣ https://github.com/gam0022/RaymarchingInUE5
 
 • 解説記事


    ‣ Object Space Raymarching in Unreal Engine 5.2 | gam0022.net
 ‣ https://gam0022.net/blog/2023/07/31/raymarching-in-ue5/
 43