レイトレースをしてみよう

プログラマーのイシドです。

今回は前々から気になっていたレイトレースについて、少し調査してみましたので記事にしたいと思います。

なぜレイトレース?

私達ゲームプログラマはリアルタイム(秒間60コマや30コマなど)の限られた時間の中でゲーム画面を描画しなければいけません。描画の仕方はGPUによってポリゴンをラスタライズする手法が一般的でした。

そもそもレイトレースにふれる機会は殆ど無く、リアルタイムといえばラスタライズ。オフラインといえばレイトレース。そんなイメージが定着しておりました。そんな中現れたのがNvidiaによるリアルタイムレイトレースデモ。全くアンテナを張っていなかったので、このデモには本当に驚かされました。

もうラスタライズの時代は終わりなのか!?と色々考えたりします。今までもそうであったように、リアルタイムレイトレースもまたエンジニアが色々試行錯誤し、ゲームに合った使い方を模索していくんだろうなと思っております。そんなところで、私もレイトレースというものを触ってみたい!と思いました。

しかしレイトレース新人な私は右も左もわかりません。グラボも無いし、DirectX12もなんか大変そうだなぁとぼんやりググっていたら、今の私に合いそうなインテルのオープンソースプロジェクトの「Embree」を発見しました。

Embree3

このライブラリはCPUで動くレイトレースライブラリです。レイを飛ばすだけのライブラリなので、ジオメトリをEmbreeに登録した後は、レイを飛ばす関数を呼ぶだけの非常にシンプルなインターフェースです。レイトレースとはなんぞや?と調べるときにすごい簡単そうに見えましたし、嬉しいことにビルド済みのバイナリもあるので、実際に簡単に使うことができました。

では早速Embreeを使ってみましょう。下記の環境で試しました。

  • Windows 10 Pro 1803
  • Intel Core i7-7700
  • RAM 16GB
  • Visual Studio 2015

Embree3を使ってみる

ダウンロード

まずはビルド済みEmbree3を落とします。こちらのサイト https://www.embree.org/downloads.html の「embree-3.6.1.x64.vc14.windows.zip」を落としました。適当な場所でZIP解凍しておきます。

お手軽に結果を確認したいので合わせてOpenGLのビルド済みも落としましょう。http://glew.sourceforge.net/ の「Binaries Windows 32-bit and 64-bit 」を落として同様にZIP解凍しておきます。

プロジェクトを作る

VisualStudioで「Win32プロジェクト」を作ります。プラットフォームを「x64」にするのを忘れずにやりましょう。

プロジェクトを右クリックし「VC++ディレクトリ」の「インクルードディレクトリ」、「ライブラリディレクトリ」にそれぞれ下記を追加。

  • 「展開したフォルダ\embree-3.6.1.x64.vc14.windows\include」
  • 「展開したフォルダ\\glew-2.1.0\include」

 

  • 「展開したフォルダ\embree-3.6.1.x64.vc14.windows\lib」
  • 「展開したフォルダ\\glew-2.1.0\lib\Release\x64」

また、各種dllファイルをプロジェクトのルートにコピーしておきましょう。

テストコード

テストしたコードの一部を載せます。

まず、デバイスを作り、シーンを作ります。

そして頂点やインデックスバッファを作り、ジオメトリにセット、そしてジオメトリをシーンにセット。特に複雑なことはありません。

レンダリングでは、対象ピクセルをワールド座標に変換し、視点からのレイを構築したら、Embree3にレイトレースしてもらいます。

後は結果を使ってピクセルのカラーを決定します。

その際に遮蔽チェックをし、見えている場合のみライトを当てます。

今回テストでレンダリングした画像はこんな感じです。

素材はすべて白ですし、トーンマップをしていないのでだいぶ白飛びしてしまっています。

また二次反射もさせていないので、レイトレースっぽくないかもしれません。

レイトレースできた

この画像は600×400の解像度でおおよそ35msかかっています。ですので、プライマリーレイの数はおおよそ秒間7MRay本です。(オクルージョンレイも飛ばしているので1ピクセル2本のレイを飛ばしています)

テストする前は『どうせ激重・・・』なんて思っていましたが、CPUでのレンダリングも思ったより高速で、このぐらいの解像度なら30FPS程度出すことができました。ちょっとびっくりです。

なお、TBBを使った分散をすればもっとパフォーマンスを稼ぐことができます。embree3のサンプルを覗くと100MRayを超えているサンプルも有りました。またインテルコンパイラ版のサンプルもあり、そっちは更に高速になっていました。

RTX2080は10GRay/sらしいので、比べると1/100程度のパフォーマンスしか出ませんが、メモリだったりのGPU的制約が無いのはやりやすいかなと思いました。

今後

実際のレイトレースではモンテカルロ積分を使ってレイを飛ばしまくったり、ロシアンルーレットを併用して二次レイを飛ばしたりすることで、よりリアリティのある絵をレンダリングすることができます。

また、レイトレースはサンプル数が少ないとブツブツした特有のノイズがのります。モンテカルロ積分は2倍の品質にするのに4倍のサンプルが必要らしいので、ある程度行くと、いくらレイを飛ばしても全然絵が変わらない!なんてことになりがちです。

そこで登場するのがデノイザーです。探すとインテルからも出ていました。

https://openimagedenoise.github.io/

急にリアルタイムレイトレースが現実的になった裏には、こういった別の技術革新があるのかもしれません。実際に今年のCEDECで行われていたリアルタイムデモの講義では、Nvidiaのデノイザーが大いに活躍していたイメージでした。

もし機会があれば、次回はデノイザーを試してみたいと思います。

最後に、今回試したソースをこちらに貼り付けておきます。

embree_test

(Visited 224 times, 1 visits today)

コメント投稿は締め切りました。