空間分割

結局やっちゃおうかなというノリで思考中。

Uniform grid
構築、探索とも容易だが極端なシーンには向かない。
また分割数を増やすと重複するデータが出現しやすい。

Octree
構築は容易と思うけど無駄が多い。
u-grid と比較すると探索が遅くなるのは致し方ないといったところか。

BSP
色々な観点から無駄が最も少ないが構築時間が最大のボトルネック
良質な分断面を選択しないとバランスの悪い木となり探索に影響が。
ポリゴンを物理的?に分断するため元入力以上のデータ数になる。


レイトレではないが BSP+Portal は以前実装したことがある。
前処理にいくらでも時間が掛かってもいいなら悪くない選択かな。
インタラクティブなシーンだと色々制限や工夫が必要になるけど。
ワンショットの静的シーンを入力とする前提ならいいかぁ。

結局ベストな選択というのは存在しない感じ。
シーン構造を解析して適切なアルゴリズムを利用することが究極なのかな。

実装の手間暇を考慮すると Octree 辺りが折衷案になりそうな予感。

MCPT その3

はてな日記使い難いなぁ、、、

スレッド化に続いて Exposure でのトーンマップをやっつけ実装。
コード書いてる時間よりも考えている(=設計)時間が長いのは当然として
毎回ネーミングに時間とられるネーミングセンスのなさが嫌になる。

Mymemory
人力系の翻訳サイトなんか便利だね。

とまぁ置いといて

最大深度: 10
サンプリング数: 5000

空間の最適化(AABB、Octree、BSP、kd-tree)などは一切していないので
恐ろしい時間が掛かった。

3439335ms

とりあえずこれで任意のシーンを HDR で描画できるようになった。

スレッドその2

MCPT のコア部分をマルチスレッド化。
テスト環境はデュアルコアなのでマルチコアも楽しんでみようということで横道に、、、
単純にアムダールの法則から理論値 2 倍は出るはずということで。

シングル: 42735ms
マルチ: 22117ms
1.93 倍

レイトレはデータ構造が単純なので問題なく達成・・・つまらん。

cpu を意図的に均等割付してみる。
xp 環境では SetThreadAffinityMask しか使えないようなのでこちらで。

マルチ: 22415ms
1.91 倍

コンテキストの切り替えオーバーヘッドとかその辺りかな。

それなりに楽しめたのでよしとしよう。

スレッド

簡単だけどそれなりのスレッドクラスを作りたいがどうしたものか。

調べてるみると
(1) コンストラクタで _beginthredex を実行するタイプ
(2) 別関数で _beginthredex を実行するタイプ
とやってるものを見かける。

symbian とか弄っていた経緯からコンストラクタでこういった処理はしたくないんだよね。
となると (2) しかないわけなんだけど、これはイイ!という実装が見当たらない。
例えば start() という関数で _beginthredex を実行する場合、pubilic メンバ関数だから
誤って何度もコールされる可能性は絶対にある。
注意書きで対処とか格好悪いよね(汗
// @warning start() は一度しか呼んではダメ!

とりあえず CloseHandle() でハンドル開放していたら OK なノリだと

void Thread::start(unsigned (__stdcall* func)(void*)){
  if(!thread_handle){
    thread_handle = (HANDLE)_beginthreadex(NULL, 0, func, this, CREATE_SUSPENDED, &thread_index);
  }
  ・・・レジューム
}

void Thread::close(){
  if(thread_handle){
    WaitForSingleObject(thread_handle, INFINITE);
    CloseHandle(thread_handle);
  }
}

// @warning close() 呼び出しを行っていない start() の動作は不定です!

とりあえずおかしな動作にはならないという最低限の保障はできるが、
利用者からすると start() をコールしているのにスレッドが走らないというのはやはり違和感のある実装。

void Thread::start(unsigned (__stdcall* func)(void*)){
  close();
  ・・・スレッド生成
}

何か走っている場合は終わるまで待ってから生成。
一応リエントランスといえばそうだけど、、、

// @warning 速やかに起動しない場合があります!

となると強制終了しかなくなるが・・・スレッド処理次第で嫌な予感がするね。
ついでにスレッドリソースの構築/破棄は明示的に指定されない限りは一度に留めておいて再利用したいところ。

厄介だねぇ・・・コメントに一筆しておくか(ゴホゴホ

MCPT その2

結局弄り出すとあれこれやっちゃいたくなるんだね、、、

最大深度: 3
サンプリング回数: 500


おかしな出力なのは光源のため。
直接照明は点光源で間接照明は面光源。
面光源のオクルージョンテストを調べなければ。

サンプリング回数が少ないと光線が光源に飛んでいってくれないことから
全体的に暗くなっちゃう。
とりあえず光源の光度を 1.0 なんかにして誤魔化してるわけだけど
全体的に明るくなるが白飛びが発生するジレンマ。
早い段階でトーンマッパーも組み込まないといけないね、、、

Monte-Carlo-Path-Tracing

前回レイトレを弄っていたものからか無性にレンダラを書きたくなってきた(汗
といっても中毒性があるのであまり大したことまではしないように触りだけ・・・。
趣味や仕事で環境光=一定加算なんてことしかしてこなかったもので
間接照明が扱えるものがいいねということからお手軽なパストレなんかを一つ。

とりあえず結果を見たいという欲求から拡散反射のみ実装。

最大深度:3回
サンプリング数:10000回

1次レイを撃つ際に(かなり適当な分布で)アンチエイリアスを考慮。
最適化は何もしていないため大したシーンでもないのに時間だけは掛かる。
肝心の間接照明効果は球の隣接する箇所にほんのり出ていますね。


■直接照明

■間接照明

■直接/間接照明

最大深度:10回
サンプリング数:100回

心理量ライティングその2

HLSL はシェーディング部分をいじるのは簡単だけどその他の準備が面倒、、、
ということで昔作ったレイトレを改修してみることにした。
拡散反射についての物理量[上]と心理量[下]の比較。
すべてγ(=2.2)補正あり。
トーンマップ部分は Exposure(K=1.0) で行った。


(1) トーンマップなし、照度 1 ルクス

(2) トーンマップあり、照度 1 ルクス

(3) トーンマップなし、照度 10 ルクス

(4) トーンマップあり、照度 10 ルクス

弄っていて思ったがトーンマップはある程度自動調整の効くレインハード方式のほうがいいね。


肝心なスライドについて記載を忘れてました。
memlog
http://blog.taikomatsu.com/2009/08/25/%E3%83%AA%E3%83%8B%E3%82%A2%E7%A9%BA%E9%96%93%E3%81%A8%E7%89%A9%E7%90%86%E7%9A%84%E3%81%AB%E6%AD%A3%E3%81%97%E3%81%84%E3%83%A9%E3%82%A4%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0/
こちらの memlog さんのサイトから DL できるようです。