blockの巣

Rustでコンパイル時レイトレーシング5

2022/02/16 22:02 公開
Compile Time Ray Tracing in Rust Ray Tracing Rust

前回記事
リポジトリ
記事の内容はコミットID50116c5e1f95af68fdfbca77c9327e8b46018dfaのものです。

今回はレイが球にヒットしたときにヒットした箇所の法線によってレンダリングするする色を変えるところまでです。
今回の変更でもconst関数特有のあれこれはないので前回との変更点を説明していきます。

レンダリング結果
レンダリング結果

今回の変更点

hit_sphere

hit_sphere関数はレイと球の交差した距離を返すようになりました
以前はヒットしたかどうかをboolで返すだけでしたが、今回はヒットした場合はその距離を、そうではない場合は-1.0を返しています。

const fn hit_sphere(center: &Point3, radius: f64, r: &Ray) -> f64 {
    let oc = r.origin() - center.clone();
    let a = dot(&r.direction(), &r.direction());
    let b = 2.0 * dot(&oc, &r.direction());
    let c = dot(&oc, &oc) - radius * radius;
    let discriminant = b * b - 4.0 * a * c;
    if discriminant < 0.0 {
        -1.0
    } else {
        (-b - sqrt(discriminant)) / (2.0 * a)
    }
}

ray_color

ray_color関数はレイと球の衝突した箇所の法線を元にした色を返すようになりました。

const fn ray_color(ray: &Ray) -> Color {
    let t = hit_sphere(&Point3::new(0.0, 0.0, -1.0), 0.5, &ray);
    if t > 0.0 {
        let n = unit_vector(&(ray.at(t) - Vec3::new(0.0, 0.0, -1.0)));
        return 0.5 * Color::new(n.x + 1.0, n.y + 1.0, n.z + 1.0);
    }
    let unit_direction = unit_vector(&ray.direction());
    let t = 0.5 * (unit_direction.y + 1.0);
    (1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0)
}

let t = hit_sphere(&Point3::new(0.0, 0.0, -1.0), 0.5, &ray);t0.0を超える場合はレイと球が交差していることになるので交差箇所の法線を元に色を返しています。
衝突していない場合は前回までと同じくuvを元にグラデーションになるような背景色を返します。

まとめ

記事の頭で書いたようにconst特有のあれこれがありませんでした。
というのもconst_trait_impl, const_fn_floating_point_arithmetic, const_mut_refs, const_eval_limit,といったfeatureを有効にしているからですが。
このあたりが早くstableでもできるようになってくれると嬉しいです。


次回は複数のオブジェクトでワールドを作りレイが交差するかを判定します。