UE4 RTX-4.23ブランチのHybrid Translucencyは何をしているのか

NVIDIAがGithub上で公開されているEpic GamesのUnreal Engine 4からブランチして管理しているRTXというBranchがあります。
ここでは、RTX関連機能の追加や、プラットフォームに依存した積極的な最適化を適用したブランチを公開しています。その中で、RTX-4.23ブランチに追加されている機能として、HybridTranslucencyという機能があります。今回はこの機能がどういうものなのかを見てみたいと思います。(2019/12/02現在)
https://github.com/NvPhysX/UnrealEngine/tree/RTX_dev

Hybrid Translucencyの機能説明

README.mdより拙訳
 この機能により、ラスターとレイトレースの半透明を同時に使用できる機能が提供されます。現在、レイトレースで扱われる半透明は、すべての半透明オブジェクトをレイトレーシングによってレンダリングします。これにより、Cascadeのパーティクルなどのサポートされていないプリミティブタイプがレンダリングされない事となります。さらに、ラスタライズ向けに作成されたコンテンツでは、多くの場合、屈折の影響が直感的でない状態で作用する可能性があります。Hybrid Translucencyは、多数のレイヤーをオフスクリーンサーフェスにレイトレースし、通常のラスター半透明の一部として、これらのレイヤーを合成します。完全なレイトレースされた半透明のOITのサポートと屈折を実現することはできませんが、レイトレースされた半透明の反射とシェーディングが提供されるので、ラスターより悪くなるということはありません。この機能を使用するためには、プロジェクト単位でHybrid Translucencyのプロパティを有効にする必要があります。これは、ベースの半透明シェーダーを切り替えて機能を有効にするためです。

Hybrid Translucencyの使い方

 Projectの設定のレンダリングの項目で、Hybrid Translucencyにチェックを入れて再起動をすれば、r.RayTracing.HybridTranslucencySupportの値が1となるはずなので、これで該当プロジェクトはHybrid Translucencyが使用可能になります。BasePassのシェーダーの一部にHybrid Translucencyを行う部分が追加されるため、プロジェクト単位の設定が必要なようです。

 r.RayTracing.HybridTranslucency.Layersで指定されたレイヤー数だけ、オフスクリーンのRenderTargetが確保されます。各レイヤーが保持するデータは、TranslucencyLayersColor(PF_FloatRGBA)とTranslucencyLayersDepth(PF_R32_Float)で構成され、これが、レイトレースをサポートされる半透明レイヤーの枚数になります。レイヤー数でサポートできる最大の重なり枚数が決まりますが、Layer数を超えたTranslucencyサーフェースのシェーディングは、単にRasterのシェーディングが使われるので、Layer数を超える枚数のレンダリングがシーン上に発生しても、レンダリングが直ちに破綻するというわけではありません。デフォルトの設定値が1であるように、あまり大きな値は必要ではないと思われます。

レンダリングパス

 Hybrid Translucencyが有効な場合は、FDeferredShadingSceneRenderer::Render()内で、RasterのTranslucency描画の直前で、RTのTranslucencyパスが描画されます。RTのTranslucencyパスは、HybridとNon Hybridが共通のコードとなっており紛らわしいですが、Hybrid Translucencyが有効な場合は、このパスでLayersColorとLayersDepthが描画されます。
 RTのTranslucencyパスは、カメラからPrimary Rayをキャストし、HitしたTranslucentサーフェースのライティングを行います。反射RayはRoughnessがTranslucencyMaxRoughness以下の場合にキャストされます。屈折Rayは、Non Hybridの場合は、Specularに設定されたIoRにしたがって屈折しますが、Hybrid Translucencyの場合は、後程Rasterが使うLayerの描画をするための処理なので、屈折処理は無効化されます。したがって、カメラからPrimary Rayが生成され、その方向にレイトレースを続けて、HitしたTranslucentサーフェースのライティングを評価し各Layerにライティングの結果を格納しています。
 RTの描画の直後で、RasterのTranslucencyパスがTranslucencyジオメトリをForward Renderingで描画します。Hybrid Translucencyが有効な場合は、LayersDepthを参照し、LayerDepthと描画しているジオメトリの深度値が閾値以下ならば、LayersColorの値をシェーディング結果と置き換える処理が挿入されています。Rasterが描画するTranslucencyジオメトリは、サーフェースのライティング処理の後、屈折先の評価を行って、設定されたOpacityにしたがって、サーフェースの描画結果とブレンドしますが、これらの処理はHybrid Translucencyが有効な場合でもRasterと変わりません。したがって、屈折先の評価は、スクリーンスペースもしくは、リフレクションプローブのサンプリング結果となるはずです。

まとめ

 上記の通り、Hybrid Translucencyと、RasterのTranslucencyの主なレンダリング結果の差異として見られるのは、Raytraced Reflectionsが有効な場合の、Translucentサーフェース上の反射Rayによるシェーディング結果(映り込み)になります。屈折側のRayの処理はRaytraceで処理が行われません。Translucentサーフェースにおいて最も大きな視覚的な差になる屈折処理をRaster側に準ずる動作にして、その代償として、ブレンド処理はすべてRasterの処理に準ずることが可能になります。そのため、CascadeやNiagaraといったエフェクトの描画結果に干渉することはありません。処理負荷も、TranslucentサーフェースによるStencilマスクが生成できるので、画面での占有率を考慮すれば十分制御可能かと思われます。Non HybridなTranslucency処理は、既存のUE4コンテンツの半透明オブジェクトと相性が悪かったため、これはHybridレンダリングの現実的な処理として使えるのではないかと考えられます。

HybridTranslucencyを無効にした場合。Translucentサーフェース上の反射は、SSRかリフレクションプローブになると思われる。

HybridTranslucencyを有効にした場合。Translucentサーフェース上の反射は、RTで処理されるが、屈折の処理は変わらない。

Raytraced Translucencyを有効にした場合。反射、屈折ともにRTで処理されるが、右側にあるCascadeのエフェクトが消失している。