"Ray Engine" GPUによるレイトキャスト (ピクセルシェーダによる三角形とRayが交差する最短距離の計算)

洋書"GPU-based Techniques for Global Illumination Effects"のChapter5の"Ray Casting on the GPU"の内容について簡単に説明したいと思います.


"Ray Engine"によるGPUによるレイキャストは以下の2段階から構成されています.
(1) 頂点シェーダによる"三角形のBounding Sphere"と"Rayを束ねたEnclosing cone"との交差テスト(省略)
(2) フラグメントシェーダによる三角形とRayが交差する最短距離の計算

"Ray Engine"では無駄な(2)の計算を省くために, (1)の交差テストを通過した三角形のみに対して, (2)の計算を行うようになっています. 今回は(2)のピクセルシェーダによる三角形とRayの最短距離の計算 について説明します.


まず, Rayの一般式は r(t) = origin + dir * tで, 始点(origin:xyz)と方向ベクトル(dir:xyz)から構成されています. ここでは, 複数のRayをピクセルシェーダからアクセスするために, Rayの始点用のデータを格納するテクスチャ(rayOriginTexture)とRayの方向ベクトル用のデータを格納するテクスチャ(rayDirTexture)を作成します.例えば, 100個のRayを使いたいときには, 幅10pixelで高さ10pixelのテクスチャデータを2枚用意して,それぞれに対して始点のデータと方向ベクトルのデータを格納します. これでRayのデータの準備はできました. これらのテクスチャをRayTexturesと呼ぶことにします.

次に, 先ほど作ったRayTexturesと同じサイズの長方形を描画します. このとき, 長方形の4つの頂点データに全てに対して, 「同じ1つの三角形の情報」を設定します. つまり, 1つの三角形とRayTexturesとの最短距離を計算する度に, RayTexturesと同じサイズの長方形を描画します. 長方形の4つの頂点データに全てに対して渡す「同じ1つの三角形の情報」は, 具体的には三角形の3つの位置座標(xyz)をまとめた3x3逆行列の3行と, 3つの頂点の法線です.

そして, 頂点シェーダでは(1)の交差テスト(省略)を通過したときに, 上記の三角形の情報をピクセルシェーダに渡します.

先ほど書いた長方形はラスタライズされて, 各フラグメントに対してフラグメントシェーダの処理が行われます. ここで1つのフラグメントは1つのRayに相当し, そのクリップ座標を使ってRayTexturesからRayの始点と方向ベクトルを復元します. そして, 頂点シェーダから受け取った三角形の情報と復元したRayから交差時の最短距離を計算し, それをZバッファのデプス値として保存します. (この計算方法は, 洋書を参考にして下さい.) そして, より近い距離にある三角形があるときだけ, Zバッファテストによってデプス値が更新されるようにします.