Rust レイトレーシング ② レイを飛ばす

e-tipsmemo.hatenablog.com


前回は画像を表示することが可能になったのでRayを飛ばす。
必要なものはカメラとスクリーンとそれらをまとめるシーンとレイ

レイトレーシングをいろいろと検索すると何故かz軸正の方向から原点を見下ろすシーンが多いようだが理由がよくわからない。
なので今回はカメラをどの位置においても良いように書いた。

座標・方向・右手方向・fov
Vector3やPoint3の型をTとしてジェネリックに書くこともできるが、
今回はシンプルにするためにとりあえずf64で行う。

デフォルトコンストラクタなどはないので自分でそれ用のメソッドを実装する。
(たいていnewという名前で実装してあったりする。)
カメラ位置と見ている点からカメラを決定するようにした。



スクリーンはカメラの視線と直行していてほしいので角度を求めてその分だけ傾ける。
f:id:katakanan:20180113233357p:plain
Rotation3で指定したベクトルを軸として、thetaだけ回転する回転行列を計算でき、それをz軸正方向ベクトルに掛けることで
スクリーンの3次元空間中でのyベクトルを求める。xベクトルはカメラの視線とyの外積をとった。(rightと平行でもある)

nalgebraのdocument
nalgebra

fovはググればたくさん説明があるので省略。
スクリーンとカメラの距離が1であることを前提にしている。


それらをまとめるシーンと指定されたスクリーン上の座標からレイを求める関数。


特筆すべきことはない。

同じscene構造体を複数のスレッド間で共有するためには

のArcが必要


宣言時にArcポインタ?でくくって
スレッド引数時にcloneする。
(よってArcによって共有されるオブジェクトはClone Traitを実装していなければならない(ような気がする))

レイを飛ばす部分

projectionはRayをスクリーンへ投影したときのu,v座標を得る関数で結局tはvと同じである。
v座標の割合によってグラデーションさせた(lerp関数)色を書き込みreturnする。

結果は以下のようになった。
スレッド数を複数にしても同じである。

f:id:katakanan:20180114103130p:plain:w300

Programming Rust: Fast, Safe Systems Development

Programming Rust: Fast, Safe Systems Development