リアルタイムレイトレーシングを先取り!Unityのpreview機能で次世代のグラフィックを使ってみよう

プロトタイピンググループ/テクニカルアーティストグループのgam0022こと細田です。

UnityのHDRPのリアルタイムレイトレーシング(略称はレイトレ)を検証しました。

まだpreview機能ですが、自分の予想よりずっと安定して動作していて、映像制作などの用途ではかなり実用的に使えそうでした。

レイトレーシングを利用することで、グラフィックスの品質向上だけにとどまらず、アーティストの本質的ではない作業も減らせる可能性も感じました。 ライトマップのベイク作業をせずにグローバルイルミネーションを実現できたり、反射やアンビエントオクルージョンの細かい調整をせずに綺麗な結果を得られました。

この記事では以下について紹介します。

  • レイトレーシングのセットアップ手順
  • ハイブリッドなレイトレーシング
  • レイトレーシングの制約事項

レイトレーシングの時代がやってきた!

数年前にはレイトレーシングは計算時間がとても長く、リアルタイムレンダリングの用途には使えないというのが一般的な認識でしたが、2018年頃からレイトレーシングを取り巻く状況が劇的に変化しました。

2018年にNVIDIAからRTXシリーズ(NVIDIA Turing GPUアーキテクチャ)のGPUが発表されました。レイトレーシング専用のコアを搭載した初のGPUです。

それに追従するように2020年にはAMDから「Radeon RXシリーズ」が発表され、次世代ゲーム機の「PlayStation 5」と「Xbox Series X」でもハードウェアレイトレーシングがサポートされました。

専用ハードウェアの登場によりレイトレーシングのリアルタイム処理がかなり現実的になりました。

グラフィックスの品質向上を実現するレイトレーシング

レイトレーシングを採用するメリットはなんでしょうか?

3DCGの描画方法はラスタライズとレイトレーシングの大きく2つに分類できます。

ラスタライズでは3Dのポリゴンを2Dのスクリーンに投影するような仕組みで3Dのシーンをレンダリングします。 パフォーマンスには優れていますが、現実の世界の光の振る舞いの再現は難しいという欠点があります。

一方、レイトレーシングでは現実の世界に近い光の振る舞いを再現できるため、グラフィックスの品質を向上に貢献できます。たとえば、以下のようなグラフィックス表現を実現できます。

  • 写実的な表現
  • ライトマップなどの事前の計算なしの大域照明(リアルタイムな大域照明)
  • 再帰的な反射や屈折

現実の世界でカメラの写真を撮影する場合を想像してみてください。太陽や蛍光灯などの光源から放たれた光がオブジェクトの物体に当たり、反射を繰り返してカメラのイメージセンサーに到達して画像が結ばれます。 レイトレーシングでは光線(レイ)の反射を追跡(トレーシング)してシミュレーションすることで、現実の世界に近い光の振る舞いを再現しながらグラフィックスを描画します。

次のアニメーションはレイトレーシングで3Dシーンを描画する様子を可視化したものです。 カメラとスクリーンを定義し、カメラの座標からスタートしてスクリーン上のある1ピクセルを通過する半直線(レイ)を考えます。 もしレイの先にオブジェクトがあれば、そのオブジェクトの色をピクセルの色とします。逆にレイの先にオブジェクトがなければ背景を描画します。 このようなピクセルの色の決定処理を、すべてのピクセルで繰り返してシーンを描画します。

元ネタはkanetaさんのシェーダーです。

一般的なレイトレーシングの実装では、カメラ側からレイを追跡するため、レイの進む方向は現実の世界とは逆向きになります。 BRDF(光が入射したときに、どの方向にどれだけの光が反射するかの関数)のヘルムホルツの相反性(入射方向と反射方向を入れ替えても同じ結果になる性質)により逆向きに追跡しても同じ結果を得られます。 また、双方向パストレーシングなど、光源側からレイを追跡する場合もあります。

Unityのレイトレーシング対応

Unity 2019.3 + HDRP 7.2.0からレイトレーシング機能はpreview版になりました。

現在もpreviewのままですが、個人的な印象としてはUnity 2021ではかなり安定して動作するようになりました。

HD レンダーパイプラインのリアルタイムレイトレーシングがプレビューになりました | Unity Blog

Unityでレイトレーシングを動かそう(セットアップ方法)

Unityでレイトレーシングを動かすためのセットアップ方法を紹介します。 画像を用いながらできるだけ詳細にわかりやすく説明します。

ハードウェア・ソフトウェア要件

Unity HRDPのレイトレーシング機能はDirectX 12のDXR(DirectX Raytracing)上に実装されており、Windows 10(バージョン1809)以上が必要になります。MacやLinuxは未対応です。

また、RTX 2060以降のレイトレーシング対応のNVIDIA製のGPUが必要になります。

前世代のグラフィックカードの一部ではNVIDIA提供のレイトレーシングのフォールバックが動くようです。

Unityを開く前に、NVIDIAドライバーを最新バージョンに更新しましょう。

詳細は公式のマニュアルを参照してください。

レイトレーシングのセットアップ手順(HDRP Wizardを利用)

HDRP Wizardを利用したレイトレーシングのセットアップ手順を紹介します。

Unityのバージョンは 2021.2.7f1 を用います。HDRPのバージョンは 12.1.2 です。

バージョンが違う場合は微妙にメニューの名前などが変わっているかもしれません。

1. プロジェクトの作成

まずはHDRPプロジェクトを新規に作成します。テンプレートに High Definition RP (HDRP) を選択します。

プロジェクトの新規作成

しばらく待つと、HDRPのデフォルトシーンが開きます。HDRPの新規プロジェクトの作成にはやや時間がかかるので、気長に待ちましょう。

HDRPのデフォルトシーン

2. HDRP Wizardによる設定変更

HDRP Wizardを開きます。メニューの Window > Rendering > HDRP Wizard から開けます。

HDRP Wizardを開くメニュー

これがHDRP Wizardの画面です。 次の2つを順番にクリックします。

  • HDRP + DXR のタブ
  • Fix All ボタン

HDRP Wizardでセットアップ

Fix Allボタンを押すと、Hold on のダイアログが表示されるので、しばらく待ちます。

Hold onのダイアログ

Unity Editorを再起動のダイアログが現れたら、 Restart Editor ボタンで再起動します。

Restart Editorを押す

3. HD Render Pipeline Assetの作成

レイトレーシング用のHD Render Pipeline Assetを作成します。

Assets/SampleSceneAssets/Settings/HDRPHighQuality.asset を選択します。

HDRPHighQuality

Ctrl-Dで複製し HDRPDXRQuality という名前をつけます。名前は任意ですが分かりやすい名前にしましょう。

HDRPDXRQuality

4. Quality Levelの作成

メニューの Edit > Project Settings... からProject Settingsを開きます。

Qualityの項目を選択し、 Add Quality Level ボタンからレイトレーシング用のQuality Levelを作成します。

Nameには DXR と名前をつけて、Render Pipeline Assetには3.の手順で作成したHD Render Pipeline Assetを指定します。

Project Settings

次にQuality LevelのDefaultをDXRにして、DXRのQuality Levelをクリックして選択状態にしておきます。

Project Settings

5. HD Render Pipeline Assetの設定

3.で作成したHD Render Pipeline Assetに修正を加えます。

.assetを直接編集しても良いですが、Project Settingsの Quality > HDRP の画面からも編集できます。

HDRPの画面で HDRPDXRQuality を選択します。

Quality > HDRP

次に、以下のチェックボックスをONにします。

  • Screen Space Ambient Occlusion
  • Screen Space Global Illumination
  • Screen Space Reflections
  • Transparent Screen Space Reflections
  • Screen Space Shadows

HD Render Pipeline Assetの設定

これでプロジェクト設定は完了です!お疲れさまでした。

6. シーンのセットアップ

レイトレーシング用のシーンを簡単に作成します。

Boxのスケールを調整して床をつくり、その上にSphereを配置したとてもシンプルなシーンを作りました。

シンプルなシーン

Box Volumeを作成します。Box Volumeの大きさを適度に調整します。

Box Volume

ProfileのNewボタンから新しいVolume Profileを作成します。

Box Volume

Add Overrideボタンから Raytracing > PathTracingを追加して、EnableをONにします。

Box Volume

以上でセットアップは完了です!

レイトレーシング(Path Tracing)のONとOFFの結果を見比べてみると、ONでは大域照明のある写実的な結果になっているのが分かります!

レイトレーシングOFF

Path Tracing OFF

レイトレーシングON

Path Tracing ON

ライトマップなどをベイクしなくても綺麗にライティングされるので、とてもありがたいですね。

床との接地面に着目すると、アンビエントオクルージョンに加えて、二次反射によって床に球体の赤い色が写り込んでいます。

その他のレイトレーシングのセットアップ方法

HDRP Wizardを利用しないその他のセットアップ方法を紹介します。

セットアップ済みのプロジェクトを使う方法

Unity公式のレイトレーシングのセットアップ済みのプロジェクトが配布されています。

レイトレーシングのセットアップは手順がちょっと多いので、セットアップせずにとりあえず使ってみたい人にはこちらがオススメです。

https://github.com/Unity-Technologies/HDRPRayTracingScenes

屈折・反射・大域照明など、レイトレーシングの機能がひととおり使われたサンプルです。

Render Pipeline Wizardを使わない方法(完全手動)

Render Pipeline Wizardを使わずに完全手動でセットアップする方法が公式マニュアルに書かれています。

Getting started with ray tracing | High Definition RP | 12.1.2

ハイブリッドなレイトレーシング

レイトレーシング専用のGPUの登場で高速化したとはいえ、まだまだパフォーマンス面には課題が残ります。

すべてをレイトレーシングでリアルタイムレンダリングにするには現代のGPUでも性能が足りません。

その解決策として ハイブリッドな レイトレーシングがあります。

すべてをレイトレーシングで計算するのではなく、ラスタライズをベースにして補助的にレイトレーシングを使います。

プライマリレイに相当する直接光の部分はレイトレーシングを使わずにラスタライズで描画を行います。

そして、反射やアンビエントオクルージョンなどの従来はスクリーンスペースのレイマーチング等で行っていたエフェクトをレイトレーシングに置き換えるハイブリッド方式がUnityのHRDPには実装されています。

たとえば、以下のようにVolume Profileを設定すれば、Global Illuminationのみレイトレーシングで計算されます。

Path Tracing(完全なレイトレーシング)の結果と比較すると、やや品質は下がりますが、十分に綺麗な結果です。

Global Illuminationのみレイトレーシング

レイトレーシングの再帰的な反射による合わせ鏡

レイトレーシングでは再帰的・複数回の反射が可能です。

従来のSSR(ScreenSpace Reflection、スクリーンスペースの反射)では、描画結果の中から反射に対応するピクセルを集めているため、3Dモデルの「後ろ姿」が反射して映り込むようなケースでは結果が破綻します。

SSR

レイトレーシングを利用すれば、後ろ姿はもちろん、合わせ鏡のように再帰的な反射が必要なケースにも対応できます!

PathTracing

検証にあたり、Lucyの3Dモデルの素材をお借りしました。

The Stanford 3D Scanning Repository

レイトレーシングの再帰的な反射による万華鏡

三角柱の内側を鏡面にして、レイトレーシングの再帰的な反射をさせることで、万華鏡をボトムアップ的なアプローチで再現できます。

ShaderGraphとの組み合わせ

ShaderGrapthとの組み合わせもできます。

ShaderGraphでEmissiveのパターンを計算すると、そのまま光源として利用できます。

ShaderGrapthでEmissive

制約事項:ddx/ddyは使えない

制約事項としては、ddx/ddy等のderivatives系に依存したシェーダーの命令を利用できません。

たとえばCheckerBoardノードは内部でddx/ddyを利用しているため、レイトレーシングと併用すると次のエラーになります。

Shader error in 'Shader Graphs/Floor': Compilation failed [0x80004005 - Unknown error.] 'error: validation errors
at 0x1a464effaf8 inside block #0 of function ?ClosestHitMain@@YAXURayIntersection@@UAttributeData@@@Z Opcode DerivCoarseY not valid in shader model lib_6_3(closesthit)
at 0x1a464efdd68 inside block #0 of function ?ClosestHitMain@@YAXURayIntersection@@UAttributeData@@@Z Opcode DerivCoarseY not valid in shader model lib_6_3(closesthit)
at 0x1a464f003e8 inside block #0 of function ?ClosestHitMain@@YAXURayIntersection@@UAttributeData@@@Z Opcode DerivCoarseX not valid in shader model lib_6_3(closesthit)
at 0x1a464f00338 inside block #0 of function ?ClosestHitMain@@YAXURayIntersection@@UAttributeData@@@Z Opcode DerivCoarseX not valid in shader model lib_6_3(closesthit)

Validation failed.

'

Compiling RayTracing program with MULTI_BOUNCE_INDIRECT _BLENDMODE_OFF _DISABLE_SSR_TRANSPARENT _REFRACTION_OFF
Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_LIGHTMAP_FULL_HDR
Disabled keywords: _SURFACE_TYPE_TRANSPARENT DEBUG_DISPLAY LIGHTMAP_ON DIRLIGHTMAP_COMBINED _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY _DOUBLESIDED_ON _ADD_PRECOMPUTED_VELOCITY _TRANSPARENT_WRITES_MOTION_VEC _ENABLE_FOG_ON_TRANSPARENT _DISABLE_DECALS _DISABLE_SSR _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN UNITY_NO_DXT5nm UNITY_ENABLE_NATIVE_SHADOW_LOOKUPS UNITY_METAL_SHADOWS_USE_POINT_FILTERING UNITY_NO_SCREENSPACE_SHADOWS UNITY_PBS_USE_BRDF2 UNITY_PBS_USE_BRDF3 UNITY_NO_FULL_STANDARD_SHADER UNITY_HARDWARE_TIER1 UNITY_HARDWARE_TIER2 UNITY_HARDWARE_TIER3 UNITY_COLORSPACE_GAMMA UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS UNITY_LIGHTMAP_DLDR_ENCODING UNITY_LIGHTMAP_RGBM_ENCODING UNITY_VIRTUAL_TEXTURING UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION UNITY_ASTC_NORMALMAP_ENCODING SHADER_API_GLES30

CheckerBoardノードを使わなければ回避できるので、市松模様の計算をFloor・Add・Moduloによる自前の実装に置き換えて解決しました。

市松模様を床にしたシーンです。

また、このシーンではPathTracingを使わずにハイブリッドなレイトレーシングでセットアップしました。 反射やアンビエントオクルージョンだけをレイトレーシングに設定しています。 設定方法はVolumeのインスペクターをぜひ参照してください。

CheckerBoardのシーン

市松模様のパターンを計算するShaderGrapth

CheckerBoardのノード

レイトレーシングではピクセルごとに独立してレイを飛ばすので、ピクセルシェーダーの同じブロックで情報の共有が必要になるderivatives系の命令が使えないのも納得できる仕様だと感じました。

レイトレーシングの制約事項(パーティクルやスキニングとの併用)

Unity 2021.2.7f1 + HDRP 12.1.2では以下のような制約事項がありました。

たとえば、以下の機能はレイトレーシングとは併用できません。

  • VFXGraph(GPUパーティクル)
  • GPUスキニング

GPU側でジオメトリーを変形や制御するような機能とのレイトレーシングの組み合わせは原理的に難しそうなので、これは仕方のない制約だと感じました。

CPU側でジオメトリー更新するCPUパーティクルやCPUスキニングであれば問題なく併用できました。

VFXGraphと反射を組み合わせたい場合はBox Volumeなどでシーンの一部だけをSSRに置き換えることでも解決できます。

感想とまとめ

今回はUnityのHDRPのレイトレーシング機能を検証してみました。 検証中にUnity Editorのクラッシュが2,3回は発生しましたが、予想よりはずっと安定して動作していました。 レイトレーシングの機能にも大きな不具合も見つからず、しっかりとサポートされているという印象を受けました。

検証を通じて、レイトレーシングの大きな魅力は 簡単に綺麗なライティング結果を得られる 点だと感じました。

これまでは大域照明のためのライトマップのベイクなどの退屈で時間のかかる作業が必要でしたが、レイトレーシングを使えば事前作業は不要になります。 従来のスクリーンスペースのアンビエントオクルージョンやSSRではシーンに合わせたパラメーターの地道な調整が必要でしたが、レイトレーシング計算ではデフォルト値でも十分に綺麗な結果になります。 レイトレーシングというとグラフィックスの品質向上に注目されがちですが、アーティストがより本質的な部分に集中できるメリットも大きいと思います。

レイトレーシングが当たり前のように使える近い未来にとてもワクワクしています!

参考資料

このブログについて

KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。

関連記事

このブログについて

KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。