This article is based on the following publication. [Interactive Indirect Illumination Using Voxel Cone Tracing: A Preview] http://maverick.inria.fr/Publications/2011/CNSGE11/index.php [GigaVoxels: Ray-Guided Streaming for Efficient and Detailed Voxel Rendering] http://maverick.inria.fr/Publications/2009/CNLE09/ All of this publication's contents that are used in following this article are belong to the original authors.
Interactive Indirect Illumination Using Voxel-Based Cone TracingのI3D2011のポスターを読んでみます。タイトルを日本語に訳すと、「ボクセル内のコーントレースを用いたインタラクティブな間接照明」といったところでしょうか。日本語率が20%ぐらいしか無い気がしますが。
これに関する一連の発表の経緯
まずI3D2011でCyril Crassin, Fabrice Neyret, Miguel Sainz, Simon Green, Elmar Eisemannによってポスター発表が行われたようです。その後、Pacific Graphics 2011,SIGGRAPH2012,GTC2012で論文として詳しく発表が行われたようです。 さらに現在はUnrealEngine4に、これを基にしたGlobal Illuminationが実装されているそうです。
概要
間接照明はリアリティのあるレンダリングにとって重要な要素です。しかしその計算コストは高く、シーンの複雑度とサーフェースのBRDFをどの程度取り扱うかに深く依存します。この発表では、複雑な事前計算なしに、低周波数成分に限らずに(拡散反射のみでなく、鏡面反射も取り扱う)、リアルタイムで大域照明モデルを 計算する革新的なアルゴリズムを紹介します。この技術は、voxel octreeで空間をモデル化することと、その中をapproximate voxel cone tracingで走査することによって、 迅速にvisibility(遮蔽の度合い)とincoming energy(届く間接光)を計算します。 このアプローチでは、ランバートモデルと、光沢のあるマテリアルを両方とも、リアルタイムで取り扱うことが出来ます。
アルゴリズム概要
- 入力光をシーンのメッシュをラスタライズすることによりSparceVoxelOctreeに書き出します
- voxelの値をフィルターして高レベルのOctreeに格納します(Mipmapの生成)
scree-space quad-tree解析によって、効率的に並列作業します
- カメラからのレンダリングを行います。
各ピクセルでFinalGathering(間接照明の適用)を行うために、半球状にいくつかのConeTracingを行うことで間接光を算出します。 直接光とあわせて入力光とします。
Sparse Voxel Octree の構造
このアプローチの肝は、Filterされた階層化されたvoxel表現のシーンジオメトリによって作られています。 最適化のために、このvoxelは”compact pointer-based sparse voxel octree”(これに関しては後述)に格納されています。 今回は小さなM=3Brick(これに関しても後述)をoctreeの末端に使用しています。 この構造に格納することで、ほぼシーンに依存しないパフォーマンスを実現し、複雑な構造のシーンにも対応できます。
“compact pointer-based sparse voxel octree”
詳しくは別の論文”GigaVoxels : Ray-Guided Streaming for Efficient and Detailed Voxel Rendering”で発表されています。 Voxel表現に関する概要は以下のとおり。
木構造(論文中ではN3-Tree。上図は単純化して説明するため、N=2のN2-Tree)の各ノードを格納する。NodePoolは3DTexture。各ノードはポインタをひとつだけ格納している。ポインタは自分の子になるノードグループの先頭を指す。 子になるノードの数は一定なのでポインタはひとつでよいという仕組み。 各ノードは自分がhomogeneous volume(空間が空もしくは一定)の場合そのconstant valueを保持し、そうでない場合はBrickへのポインタを指す。 Brickは木構造をしていない単純なvoxel表現で、木構造の末端を表現する。こちらも3次元なのでM3-Brickとなる。
この論文の例では、NodePoolはLA32の3DTextureで実装され、32BitのLuminanceにフラグが2bitとXYZ各10Bitの自分の子になるノードグループへのポインタ(3DTexuteの座標位置) を格納し、32BitのAlphaにRGBA8のconstant value(homogeneous volumeの場合)かXYZ各10BitのBrickへのポインタ(3DTextureの座標位置)を格納している。 BrickPoolはBrickにどのような情報を格納するかによって変わると思われるが、3D Textureが使用されている。 ちなみに、この論文発表当時に使用されたのはGeForce8800GTSなので、あくまでComputeShaderが無い前提で記述されてる。 NとMの値は条件に応じて変えることが出来る。N=2ならば通常の8分木となり、Mは末端voxelの要素数を決定する。
Pre-integrated Voxel Cone Tracing
このアプローチでは、visibility(遮蔽項),energy(直接光のirradiance),NDF(NormalDistributionFunction?)といったvoxel内の情報を、錐体状にMipmap化されたvoxel内を、ひとつのrayで走査することで概算します。 これは錐体の形状で積分(合算)する過程で、その錐体形状の半径に対応するMipmapを参照することで実現します。 この過程でスムースなLOD遷移を実現するために、quadrilinear interpolation(2DTextureでいうところのTri-linear補間のようなもの)を使用します。 voxelシェーディングではBRDFをConvolutionし、NDF,Lightの方向、ViewConeの大きさなどは、GaussianLobeで表現しています。 GaussianLobeは、方向情報の分布を圧縮して格納する方法で、非正規化ベクトルで格納します。
Anisotropic Pre-Integration
低解像度voxel(高Mipmapレベル)を使用する際に、高品質なvisibilityの計算と、 light leaking(voxelの粒度によって本来遮蔽されているはずの光が反対側に届いてしまう)を抑制するために、voxel内の情報を方向別に保持します。 6方向分の情報を、各々近い3方向分の線形補間で算出します。 これによって1.75倍のストレージと、サンプリングに多少の時間がかかるようになりますが、より高品位な結果が得られます。
感想
なんとなくですが、この技法の概要が理解できた気がします。 基本的には、シーンの表現にvoxel表現を用いています。従来のLPV(Light Propagation Volumes) 技法ではRSM(Reflective Shadow Map)からinjectionした直接光と遮蔽情報をSHで表現して、隣接voxelに伝播させることで間接光を演算していましたが、この手法ではvoxelに直接光をinjectionする部分までは基本的に同じですが、間接光を演算する際にvoxel内を走査することで演算しています。voxel内の走査を単純に行えば、間違いなく演算量が爆発的に増えますが、あらかじめvoxelのMipmapを生成することと、ConeTracingによって効率よく情報を集めることで、 リアルタイムで実現可能な速度でこれを実現しています。
また、voxel内を走査する手法をとることでメリットが生まれます。
- 空間的に比較的遠いところからも間接光が届く
(LPVですと、voxelの粒度を細かくすると伝播するための反復計算の回数が増えるというジレンマがありました。) - どのようなシェーディングモデルにも理論的には対応可能
間接光はConeTracingでサンプリングする際に選択するので、どのような分布形状にも対応できそうです。(LPVで間接光表現に低次のSHを使用する場合は、伝播計算を反復すると、光源の方向成分が意味消失し易かった。 結果的に一様反射には比較的適用し易かったが、選択性のある反射に適用するのが難しい側面がありました。) - 間接光演算にLODを適用できる
このポスター発表では触れられていませんが、ConeTracingで、どのMipmapを走査するか、どの程度遮蔽されたら走査を終了するのか、 またConeTracingを何回行うか等を変化させることで、計算負荷と品質のトレードオフを図ることが可能だと思われます。 カメラからの距離や、キャラクタの重要度に応じてこれらを変化させて計算負荷をマネージメントすることも可能かも知れません。
一方で不明な部分もあります。
- 直接光のinjection手法
従来のRSMによるものなのか?効率的なストアの方法は?ジオメトリ(遮蔽情報)を別途追加しているのか? - voxelにMipmapを適用する際のscree-space quad-tree解析
これに関する解説はこのポスター発表には載ってないようです。 - voxel内に格納されている情報
間接光演算だけならば、遮蔽項とradiance(間接光の)のdistributionが分かれば十分だと思うのですが。BRDFとNDFを別途格納しているのはなぜ?
次回はPacific Graphics 2011に出された論文のほうを読んでみたいと思います。