技術

放射束の格納に一様グリッドを用いる方法はだめかも

前回、テクセルの歪みによる収束スピードの差を無くすにはシーン空間を一様なグリッドに区切ってそのなかに放射束情報を格納すればよくね?って事を書いたけど、実際にやってみたら確かに前回書いたような問題は解決したが、新たに解決が難しそうな問題が表面化した。
UG_P100m
斜めになってる箱の側面や赤い壁(こちらも実は微妙に斜めになってる)に筋のようなものが見える。
これは多分、一様グリッド(AABB)が斜めになってる物体表面とマッチしなくて、二次元画像で起きるエイリアシングのようなものが三次元上で起きてるんだと思う。
もう少し具体的に言うと、「グリッドが物体表面で切り取られたときの断面積」が他より明らかに小さいグリッドにおいて、フォトンの当たりづらさにより、暗くなっていると思われる。
(あと色合いも微妙におかしい。ただこれは多めにフォトンを飛ばすと今までと同じ感じになるので、収束に時間がかかるようになっただけだと思う。)

ちなみに一様グリッドといっても概念的な意味であり、実際はunordered_mapを使って物体表面付近のグリッドだけ保持するようにしてる。
なのでスパースボクセルと言ったほうがいいのかな。よくわからんけど。

これでも一応、グリッドの細かさなどのパラメータを色々調節したり、放射照度の推定で近傍ボクセルを多めに参照して3次元でガウシアンフィルタをかけてみたり、グリッドの断面積を近似ではあるが計算して放射照度の計算時に考慮したりしてるんだけど、これまでのプログラムより大幅に遅くならない範囲だとこの程度の品質が限界かも。
このような対策し無しだと黒い縞模様がはっきり見える。

リアルタイムレンダリング方面では(あくまで概念的には)似たような方法でGIを実現してたような気がするけど、うちと同じような問題は起きないんだろうか。
てか起きてたら話にならないから、何らかの対策方法があるんだろう。
あるいはグリッドといっても八分木的なデータ構造を使ってるから同じ問題は起きないのだろうか。
そもそもやってることが全然違う可能性もある。

ということで、一様グリッドに放射束を格納する方法は諦めて、kd木を使おうかなと思う。
巡り巡って元に戻ってしまった感じ。
ただ、普通に衝突点の情報を全部kd木に追加すると例えば1億フォトンとかのトレースでメモリ容量的にやばくなるので、分割して実行する方法、例えば1億フォトンなら100万フォトンx100回に分割するとか、あるいはkd木に全ての情報を格納するんではなく、ある粒度で要素をまとめるようにするとか、とにかく多少ひねった方法にする予定。

それにしても学が無くて手探りでやってるから時間がかかる。
でも自分で言うのもなんだけど実装は早い。
一様グリッドの方法はコード書き始めて1時間程度でとりあえず動くものが出来た。
でもそんな自慢はくだらない。

くだらないってのは謙遜ではなくて、このくらい問題が難しくなると、いくら手探りが素早かろうが、数式等を扱ってある程度の方向性を見いだせるような学がある人と比べるとその足元にも及ばないっていうのを本当に実感してるから。

そういう人になりたいと思ってるし、多少はそういう努力はしてるけど、とても時間がかかると思う。
他にもやらなきゃいけない事ややりたい事は色々あるから難しいかもしれない。
お金もらって大学行ければいいのに。なんてね。
まぁぼちぼちやっていこう。

コメントを残す

メールアドレスが公開されることはありません。



※画像をクリックして別の画像を表示

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください