GIとシェーダ

もともと最初の開発目的が特殊効果系をうまくレンダリングできるレンダラーだったということもあって、nytrでも是非シェーダはサポートしたい。
といってもレイトレではマイクロポリゴン法とは違い、シェーダの並列実行は難しいのでおそらくC++でシェーダを書くことにはなるとは思う。

そこで問題になってくるのが、最近のGIアルゴリズム

今の設計だとシェーダクラスは、

  • 視点方向からのレイに対してRadiance計算
  • フォトンが当たった場合の反射方向計算兼Russian Roulette

の計算をすることになってて、各メンバ関数で各種BRDFの構築、構築したBRDFに対してのRenderManでいうgather()計算をしてる。

ただ、双方向系のアルゴリズムメトロポリス光伝達法(MLT)だと完全にパスを構築した後の計算が必要になり、今の再帰的にしかかけないシェーダ実装だとまずいことになる。解のひとつとしてはPBRTがとっている手法(シェーダでは加算のみのBRDF群を生成し、あとは完全にレンダラ側が処理)があると思うけど、ちょっとこれには抵抗があるかな。
とりあえずMLTや双方向パストレで特殊効果を再現するのは不可能に近いので、そこでは完全にPhysically-basedな計算をすることにして、Whittedなレイトレで特殊効果が可能なケースのみ特殊効果系サポートということにします。

こんな感じになりそう。
class Material

  • f_r(\omega_i, \omega_o)計算
  • f_r(\omega_i, \omega_o)計算、w_iサンプリング
  • f_r(\omega_i, \omega_o)計算、w_oサンプリング+RussianRoulette有(フォトンマッピング用)
  • L(x, p)計算。視点方向からのレイに対してRadiance計算(Whittedレイトレでのみ使用)

一番上のみの実装でレンダリング自体は可能なはず。あと3つは必要なら実装。でももっと簡略化できないかなぁ。