🦀

RustでRayTracing (チャプター8.3まで)

2021/01/13に公開

チャプター8.1と8.2

randを使ってvector3のランダムを実装しました。
Vector3はf32の型しかほぼ使ってなかったので、型パラメータで実装する必要はないかなと思ったんですが、勉強のためにやってみたら、whereがあることを思い出せたので良かったです。
すごくHaskell感がして好きです。
rustのコンパイルエラーがすごく優秀なので、それに従って型を直しました。

実装したコードを載せておきます。

fn random_vector3<T>() -> Vector3<T>
where Standard: Distribution<T>
{
    vec3(rand::random::<T>(), rand::random::<T>(), rand::random::<T>())
}

fn random_vector3_range<T>(min: T, max: T) -> Vector3<T>
where Standard: Distribution<T>, T: SampleUniform + PartialOrd + Copy
{
    let mut rng = thread_rng();
    vec3(rng.gen_range(min..max), rng.gen_range(min..max), rng.gen_range(min..max))
}

ray_color関数が再帰になり、かなり処理時間がかかるようになりました。
cargo runでやってると終わらないので、build --releaseしてから実行するようになりました。
高速化したときが楽しみですね。

チャプター8.3

ガンマ補正はwrite_colorのところで平方根とるだけなのですが、上のような画像が出力されました。
真ん中に変な線があったり、波打った感じになってて、自分の実装をうたがったのですが、sqrt追加しただけだしなと。

いままでf32ですべての処理をやってたんですが、倍精度のf64でやればいいんじゃないかと思ったので、コードを書き直して実行したら、改善されて、以下のような画像が出力されました。

どこの処理がf32でよくて、どこの処理がf64でいいのか切り分けられれば、より効率良く実行できる気がするのですが。
たまたま問題が表面化したのがここで、もともとf64で実装しなきゃいけないのかもしれないですね。
ハードウェアの知識があると、どうしてもビット数をケチりたい衝動に。

Discussion