プロトタイピンググループ/テクニカルアーティストグループの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ピクセルを通過する半直線(レイ)を考えます。 もしレイの先にオブジェクトがあれば、そのオブジェクトの色をピクセルの色とします。逆にレイの先にオブジェクトがなければ背景を描画します。 このようなピクセルの色の決定処理を、すべてのピクセルで繰り返してシーンを描画します。
シェーダーは最強の作図ツールなので、
— がむ (@gam0022) December 27, 2020
レイトレーシングの原理を説明するための図をUnityシェーダーだけで作りました。 pic.twitter.com/VuLBhoqEaY
元ネタはkanetaさんのシェーダーです。
一般的なレイトレーシングの実装では、カメラ側からレイを追跡するため、レイの進む方向は現実の世界とは逆向きになります。 BRDF(光が入射したときに、どの方向にどれだけの光が反射するかの関数)のヘルムホルツの相反性(入射方向と反射方向を入れ替えても同じ結果になる性質)により逆向きに追跡しても同じ結果を得られます。 また、双方向パストレーシングなど、光源側からレイを追跡する場合もあります。
Unity 2019.3 + HDRP 7.2.0からレイトレーシング機能はpreview版になりました。
現在もpreviewのままですが、個人的な印象としてはUnity 2021ではかなり安定して動作するようになりました。
HD レンダーパイプラインのリアルタイムレイトレーシングがプレビューになりました | Unity Blog
Unityでレイトレーシングを動かすためのセットアップ方法を紹介します。 画像を用いながらできるだけ詳細にわかりやすく説明します。
Unity HRDPのレイトレーシング機能はDirectX 12のDXR(DirectX Raytracing)上に実装されており、Windows 10(バージョン1809)以上が必要になります。MacやLinuxは未対応です。
また、RTX 2060以降のレイトレーシング対応のNVIDIA製のGPUが必要になります。
前世代のグラフィックカードの一部ではNVIDIA提供のレイトレーシングのフォールバックが動くようです。
Unityを開く前に、NVIDIAドライバーを最新バージョンに更新しましょう。
詳細は公式のマニュアルを参照してください。
HDRP Wizardを利用したレイトレーシングのセットアップ手順を紹介します。
Unityのバージョンは 2021.2.7f1
を用います。HDRPのバージョンは 12.1.2
です。
バージョンが違う場合は微妙にメニューの名前などが変わっているかもしれません。
まずはHDRPプロジェクトを新規に作成します。テンプレートに High Definition RP
(HDRP) を選択します。
しばらく待つと、HDRPのデフォルトシーンが開きます。HDRPの新規プロジェクトの作成にはやや時間がかかるので、気長に待ちましょう。
HDRP Wizardを開きます。メニューの Window > Rendering > HDRP Wizard
から開けます。
これがHDRP Wizardの画面です。 次の2つを順番にクリックします。
HDRP + DXR
のタブFix All
ボタンFix Allボタンを押すと、Hold on
のダイアログが表示されるので、しばらく待ちます。
Unity Editorを再起動のダイアログが現れたら、 Restart Editor
ボタンで再起動します。
レイトレーシング用のHD Render Pipeline Assetを作成します。
Assets/SampleSceneAssets/Settings/HDRPHighQuality.asset
を選択します。
Ctrl-Dで複製し HDRPDXRQuality
という名前をつけます。名前は任意ですが分かりやすい名前にしましょう。
メニューの Edit > Project Settings...
からProject Settingsを開きます。
Qualityの項目を選択し、 Add Quality Level
ボタンからレイトレーシング用のQuality Levelを作成します。
Nameには DXR
と名前をつけて、Render Pipeline Assetには3.の手順で作成したHD Render Pipeline Assetを指定します。
次にQuality LevelのDefaultをDXRにして、DXRのQuality Levelをクリックして選択状態にしておきます。
3.で作成したHD Render Pipeline Assetに修正を加えます。
.assetを直接編集しても良いですが、Project Settingsの Quality > HDRP
の画面からも編集できます。
HDRPの画面で HDRPDXRQuality
を選択します。
次に、以下のチェックボックスをONにします。
これでプロジェクト設定は完了です!お疲れさまでした。
レイトレーシング用のシーンを簡単に作成します。
Boxのスケールを調整して床をつくり、その上にSphereを配置したとてもシンプルなシーンを作りました。
Box Volumeを作成します。Box Volumeの大きさを適度に調整します。
ProfileのNewボタンから新しいVolume Profileを作成します。
Add Overrideボタンから Raytracing > PathTracing
を追加して、EnableをONにします。
以上でセットアップは完了です!
レイトレーシング(Path Tracing)のONとOFFの結果を見比べてみると、ONでは大域照明のある写実的な結果になっているのが分かります!
レイトレーシングOFF
レイトレーシングON
ライトマップなどをベイクしなくても綺麗にライティングされるので、とてもありがたいですね。
床との接地面に着目すると、アンビエントオクルージョンに加えて、二次反射によって床に球体の赤い色が写り込んでいます。
HDRP Wizardを利用しないその他のセットアップ方法を紹介します。
Unity公式のレイトレーシングのセットアップ済みのプロジェクトが配布されています。
レイトレーシングのセットアップは手順がちょっと多いので、セットアップせずにとりあえず使ってみたい人にはこちらがオススメです。
https://github.com/Unity-Technologies/HDRPRayTracingScenes
屈折・反射・大域照明など、レイトレーシングの機能がひととおり使われたサンプルです。
Render Pipeline Wizardを使わずに完全手動でセットアップする方法が公式マニュアルに書かれています。
Getting started with ray tracing | High Definition RP | 12.1.2
レイトレーシング専用のGPUの登場で高速化したとはいえ、まだまだパフォーマンス面には課題が残ります。
すべてをレイトレーシングでリアルタイムレンダリングにするには現代のGPUでも性能が足りません。
その解決策として ハイブリッドな レイトレーシングがあります。
すべてをレイトレーシングで計算するのではなく、ラスタライズをベースにして補助的にレイトレーシングを使います。
プライマリレイに相当する直接光の部分はレイトレーシングを使わずにラスタライズで描画を行います。
そして、反射やアンビエントオクルージョンなどの従来はスクリーンスペースのレイマーチング等で行っていたエフェクトをレイトレーシングに置き換えるハイブリッド方式がUnityのHRDPには実装されています。
たとえば、以下のようにVolume Profileを設定すれば、Global Illuminationのみレイトレーシングで計算されます。
Path Tracing(完全なレイトレーシング)の結果と比較すると、やや品質は下がりますが、十分に綺麗な結果です。
レイトレーシングでは再帰的・複数回の反射が可能です。
従来のSSR(ScreenSpace Reflection、スクリーンスペースの反射)では、描画結果の中から反射に対応するピクセルを集めているため、3Dモデルの「後ろ姿」が反射して映り込むようなケースでは結果が破綻します。
レイトレーシングを利用すれば、後ろ姿はもちろん、合わせ鏡のように再帰的な反射が必要なケースにも対応できます!
検証にあたり、Lucyの3Dモデルの素材をお借りしました。
The Stanford 3D Scanning Repository
三角柱の内側を鏡面にして、レイトレーシングの再帰的な反射をさせることで、万華鏡をボトムアップ的なアプローチで再現できます。
SceneViewのキャプチャ
— がむ (@gam0022) July 17, 2021
三角柱の内側を鏡面にして、レイトレーシングの再帰的な反射をさせることで、万華鏡をボトムアップ的なアプローチで再現しています。 pic.twitter.com/CAfR5Sg2zG
ShaderGrapthとの組み合わせもできます。
ShaderGraphでEmissiveのパターンを計算すると、そのまま光源として利用できます。
制約事項としては、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のインスペクターをぜひ参照してください。
市松模様のパターンを計算するShaderGrapth
レイトレーシングではピクセルごとに独立してレイを飛ばすので、ピクセルシェーダーの同じブロックで情報の共有が必要になるderivatives系の命令が使えないのも納得できる仕様だと感じました。
Unity 2021.2.7f1 + HDRP 12.1.2では以下のような制約事項がありました。
たとえば、以下の機能はレイトレーシングとは併用できません。
GPU側でジオメトリーを変形や制御するような機能とのレイトレーシングの組み合わせは原理的に難しそうなので、これは仕方のない制約だと感じました。
CPU側でジオメトリー更新するCPUパーティクルやCPUスキニングであれば問題なく併用できました。
VFXGraphと反射を組み合わせたい場合はBox Volumeなどでシーンの一部だけをSSRに置き換えることでも解決できます。
今回はUnityのHDRPのレイトレーシング機能を検証してみました。 検証中にUnity Editorのクラッシュが2,3回は発生しましたが、予想よりはずっと安定して動作していました。 レイトレーシングの機能にも大きな不具合も見つからず、しっかりとサポートされているという印象を受けました。
検証を通じて、レイトレーシングの大きな魅力は 簡単に綺麗なライティング結果を得られる 点だと感じました。
これまでは大域照明のためのライトマップのベイクなどの退屈で時間のかかる作業が必要でしたが、レイトレーシングを使えば事前作業は不要になります。 従来のスクリーンスペースのアンビエントオクルージョンやSSRではシーンに合わせたパラメーターの地道な調整が必要でしたが、レイトレーシング計算ではデフォルト値でも十分に綺麗な結果になります。 レイトレーシングというとグラフィックスの品質向上に注目されがちですが、アーティストがより本質的な部分に集中できるメリットも大きいと思います。
レイトレーシングが当たり前のように使える近い未来にとてもワクワクしています!
KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。
合わせて読みたい
KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。