e-tipsmemo

ごった煮

Rust レイトレーシング

e-tipsmemo.hatenablog.com
書きながら再び書き直した。

f:id:katakanan:20200820213000p:plain

Thu Aug 20 20:06:12 JST 2020
Hello World
1600x800
thread  : 12
ss      : 100

________________________________________________________
Executed in  143.56 secs   fish           external
   usr time  1384.58 secs    0.00 micros  1384.58 secs
   sys time    0.92 secs    0.00 micros    0.92 secs

Thu Aug 20 20:08:36 JST 2020

その中で色々あったことを書く。

Chapter 5:Surface normals and multiple objects

        if d > 0.0 {
            let tmp = (-b - d.sqrt()) / (2.0 * a);
            if t0 < tmp && tmp < t1 {
                let p = r.point_at_paramete(tmp);
                return Some(HitRecord {
                    t: tmp,
                    p: p,
                    n: (p - self.center).normalize(),
                });
            }
        }

直線と球の交点が2つ存在してもう片方を考慮するのを忘れていた。(本をちゃんと見ていなかった)
もう一つの交点を忘れると、あとの方でガラス球の反射がおかしくなる。

Chapter 7: Diffuse Material

Diffuse Materialを実装して、ガンマ補正をしていないとかなり暗なると書いてある。
本に掲載されている画像もかなりくらい。
しかし実装したら暗くなかった。
f:id:katakanan:20200820223652p:plain
gamma = 0.5だと明るすぎる気がするので0.65に。
image crateが悪い?

Chapter 8: Metal / Chapter 9:Dielectrics

これまた球の交差計算で
HitRecordの法線をnormalize(正規化)で求めている。

        if d > 0.0 {
            let sqrt_discriminant = d.sqrt();
            let tmp = (-b - sqrt_discriminant) / (2.0 * a);
            if t0 < tmp && tmp < t1 {
                let p = r.point_at_paramete(tmp);
                return Some(HitRecord {
                    t: tmp,
                    p: p,
                    n: (p - self.center).normalize(),
                    mat: self.mat.clone(),
                });
            }

            let tmp = (-b + sqrt_discriminant) / (2.0 * a);
            if t0 < tmp && tmp < t1 {
                let p = r.point_at_paramete(tmp);
                return Some(HitRecord {
                    t: tmp,
                    p: p,
                    n: (p - self.center).normalize(),
                    mat: self.mat.clone(),
                });
            }
        }

これは法線というベクトルを計算する意味では間違っていないと思うが、、
レイトレーシング的にはマイナスの半径を持つ球体を用意したりするらしいので、そのときに計算がおかしくなる。
(法線の符号が逆になる)

normalizeは normで割っているので、正の値で割ることになるが、
この本のプログラムでは 球の半径で割るのが正しい(マイナスになり得る)。
ので、こう。

n: (p - self.center) / self.radius,

その他

マルチスレッドで色々と面倒だった気がする(忘れ)
GitHub - katakanan/raytrace_one_week


参考