イベント
[GDC 2018]ついにDirectXがレイトレーシングパイプラインを統合。「DirectX Raytracing」が立ち上がる
そもそもレイトレーシングとは
これまでのリアルタイム3Dグラフィックスは「ラスタライズ法」と呼ばれる手法のレンダリングパイプラインを採用してきた。
3D空間内に存在するオブジェクトをポリゴン単位で処理し,各ポリゴンをラスタライザにてピクセルに分解。そのうえでピクセルごとにライティング(※光を当てる処理)やシェーディング(※ライティングに連動して材質の特性に沿った色を返す処理)を行うという流れだ。
ラスタライズ法では,視点から見えるポリゴン以外をレンダリングパイプラインから捨てるという,大胆な最適化手法を採用する。なので,視点の前にあるオブジェクトであっても,視点からの画角に含まれないものは「存在しないもの」として捨ててしまうのである。
当然のことながら,ラスタライズ法では視点から直接見えるものだけをライティングおよびシェーディングすることになるため,視点から見えないものが関与するレンダリングを正しく処理できない。
「視点から見えないものに配慮する必要なんてないのでは?」と思うかも知れないが,そうでもなかったりする。
たとえば映像や写真における「足元の水面に映り込む,樹木の葉」は分かりやすい例だろう。視界には直接見ている水面しか映っていないが,その水面の鏡像には画面に映っていない視界外頭上の葉々が映り込んでいるわけだ。
一方で,レイトレーシング法は少し仕組みが違う。
最終的に描画するのは画面に描かれるべきピクセルではあるものの,それにあたっては,画面内はもちろんのこと,画面外に存在する3Dオブジェクトにも配慮するのだ。
レイトレーシング法では,あるピクセルを描画するとして,視点からこのピクセルを通過する視線を放つことから始める。これが「レイ」(ray,光線)である。
このレイがオブジェクトに衝突するまで3D空間の中を進めていき,衝突したら当該3Dオブジェクト表面上の材質に対してライティングとシェーディング(の演算)を行う。ここまではラスタライズ法のレンダリングとそっくりだが,レイトレーシング法では,この「衝突した3Dオブジェクト」の表面から,さらにレイを投げることができるのだ。
視線の反射方向にレイを飛ばして,その先にある別の3Dオブジェクトに衝突したら,そこのライティングとシェーディンクを計算する。そして,その計算結果を「レイを放った元の場所」に持ち帰って適用すれば「映り込みとしての鏡像」が得られる。
いま紹介した例では視線の反射方向にレイを投げたが,仮に光源のある方向にレイを投げ,別の3Dオブジェクトに衝突した場合は「第三者に遮蔽されている」,つまりは「影になっている」ことが分かるわけだ。
まとめると「ラスタライズ法」は「処理負荷が低い分,得られる描画結果は妥協点が大きい」ということになり,レイトレーシング法は「処理が複雑だが,得られる描画結果はかなり正確」ということになる。
We've been working with @Microsoft for the past few months to develop practical, real-time applications for #DirectX #Raytracing. Our own Maksim Aizenshtein is now onstage to share our work on improving reflections in games. #GDC18 pic.twitter.com/jNP1JEmCZQ
— Futuremark (@Futuremark) March 19, 2018
DXRのアーキテクチャ
というわけで本題。一言で「DXRとはなんぞや」を語るとすれば,この「複雑ながら正確な結果が得られるレイトレーシングをDirectX 12に統合したもの」ということになるだろう。
そんなMcMullen氏は,セッションでDXRのアーキテクチャの概要解説を行った。
それによると,第1ステップとしてDXRでは,3Dオブジェクトが存在する3D空間をボトム(=下位)とトップ(=上位)の2段階で定義するところから始まるという。
ボトムは椅子や机,樹木といった3Dオブジェクトを形成するジオメトリ実データ(=ポリゴン)だ。トップはそうした各3Dオブジェクトのインスタンスデータからなる。
たとえば3Dシーンにおいて同じ椅子が複数配置されていて,それぞれが色違いで違う向きで配置されていれば,トップでは複数個の椅子モデルがそれぞれ指定のテクスチャや座標,向きの情報違いで設定される。
そのとき,当該3Dシーンの定義構造には,いわゆる「Bounding Volume Hierarchy」(バウンディングボリューム階層構造,BVH)を利用できる。つまり,放ったレイの初期衝突判定を「大まかな箱」(=Bounding Volume)単位で行うテクニックを利用可能ということだ。
第2ステップは,レイトレーシングのレンダリングパイプライン生成だ。
なぜわざわざ明示的に生成するのかというと,ラスタライズ法とレイトレーシング法では実務処理系が似て非なるものになるからである。
ラスタライズ法のレンダリングパイプラインでは,たとえばデプスシャドウ法による影生成フェーズなら,テクスチャの適用などを行うことなく,光源位置からシーンを見降ろした画角でジオメトリだけを描画する。一般的な視点からの描画においても,通常の「材質ベースの3Dオブジェクト」を先に描画して,表面下散乱を伴う「人肌もの」の描画は後回しで行ったりと,多段のレンダリングになる。
それに対してレイトレーシング法の場合,投げたレイが3Dオブジェクトに衝突したら,その3Dオブジェクトが「普通の材質」なのか「人肌もの」なのかを区別せず,きちんとライティングとシェーディングの計算を行う必要がある。そのため,テクスチャなど,当該3Dシーンで定義されるすべての材質の情報を準備する必要がある。なので,明示的に生成しないといけないのだ。
第3ステップは,実際に「レイを放つ」(Dispatch Rays)フェーズとなる。従来のラスタライズ法でいうところの「描画コール」(DrawCall)フェーズに相当するという理解でいい。
さて,これまでのDirectXもシェーダプログラムはHLSL(High Level Shader Language)で書かれていたわけだが,DXRでは新しいタイプのHLSLプログラムを書くことになるそうだ。
1つは,実際の「レイを放つ」実務を行う「Ray-Generation」シェーダである。Ray Genrationシェーダは,「定義された3Dシーン」の中でレイを進ませる制御を行うので,一種のメインループに相当する。
このレイが何らかの3Dオブジェクトに当たったら,「Hit」シェーダに処理が飛ぶ。
このHitシェーダでは主に,レイが衝突した先の材質ライティングやシェーディングを行うことになる。テクスチャを読み出して適用したりもするので,従来のラスタライズ法で言うところのピクセルシェーダによく似た仕事ということになるだろう。
突き進んだレイが3Dオブジェクトに衝突して,その3Dオブジェクトの材質処理をしてからも,さらにレイを突き進めていくなどの処理を制御したい場合は「Any Hit」シェーダを活用することになる。
たとえば,突き進んでいるレイが3Dオブジェクトに衝突するたび,そのとき持っていた色の値を減退させつつも,どんどんレイを先に進めていくような処理をすれば,半透明のような表現を行える。あるいは光源に向かってレイを進めていて,最初に3Dオブジェクトと衝突した時点で「エネルギーゼロ」を持って帰るように指定すれば影生成を行える。
もし,放ったレイがどの3Dオブジェクトにも衝突せず3Dシーンを突き抜けてしまった場合は,「Miss」シェーダを起動する。ここで「雲が浮かぶ空」などといったスカイボックスのテクスチャを取ってくるようにすれば,空模様などの最遠背景をシーン上で描けることになる。
DXRはDirectX 12世代のGPUで動作可能。リリースは今秋予定
以上がDXRのアーキテクチャ概要になる。
McMullen氏の話を聞いていた限り,NVIDIAが展開しているCUDAベースのレイトレーシングエンジン「OptiX」と構造はよく似ているような気がした。もっとも,近代的なプログラマブルレイトレーサーはみんなこのようなアーキテクチャなのかもしれないが。
気になる具体的な当面のDXRの活用法としては,冒頭でも軽く触れたとおり「『普通の』シーンの描画は従来どおりラスタライズ法で」行ったうえで,「影生成や映り込み(=鏡像)の生成をDXRで行う」という方針を,氏はほのめかしていた。
今日(こんにち)のゲームグラフィックスにおいて,影生成にはデプスシャドウ技法を使うのが定番だが,影生成のためのシャドウマップ解像度が低いと影に強いジャギーが出てしまう難点がある。レイトレーシング法であれば,画面解像度に最良の解像度の影生成が行えるようになるから,メリットは大きい。
映り込み表現では,最近だとレンダリング結果としてのフレームを素材として使って,画面座標系で局所的なレイトレーシングを行って鏡像を得る「Screen-Space Reflection」(スクリーンスペースリフレクション,SSR)が定番化している。SSRだと画面外にある3Dオブジェクトを画面内に映し込ませることができないが,レイトレーシング法に置き換えれば,その問題は解決するはずである。
DXRを利用できるGPUは基本的に,DirectX 12対応済みのものならOKらしい。実際,メカニズムとしてはGPUのCompute Shader――いわゆるGPGPUモード――で動作するため,DXR専用のシェーダコアが必要なわけではなかったりする。
ただ,まだ仕様が完全に確定していないため,どのGPUでどの程度のハードウェアアクセラレーションが有効になるかは,現状,はっきりしていないとのことだった。
ゲームグラフィックスは,2000年発表のDirectX 8から始まったプログラマブルシェーダアーキテクチャの採用で大きな変革があったが,あれから18年。ついに今年,新しいパラダイムシフトが起こるかもしれない。
Microsoft DirectX Developer Blog「Announcing Microsoft DirectX Raytracing!」(英語)
- 関連タイトル:
DirectX
- この記事のURL: