Rustでコンパイル時レイトレーシング5
2022/02/16 22:02 | 公開 |
前回記事
リポジトリ
記事の内容はコミットID50116c5e1f95af68fdfbca77c9327e8b46018dfa
のものです。
今回はレイが球にヒットしたときにヒットした箇所の法線によってレンダリングするする色を変えるところまでです。
今回の変更でもconst
関数特有のあれこれはないので前回との変更点を説明していきます。
レンダリング結果
今回の変更点
hit_sphere
関数がレイと球の交差した距離を返すようになったray_color
関数がレイと球の衝突した箇所の法線を元にした色を返すようになった
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);
のt
が0.0
を超える場合はレイと球が交差していることになるので交差箇所の法線を元に色を返しています。
衝突していない場合は前回までと同じくuvを元にグラデーションになるような背景色を返します。
まとめ
記事の頭で書いたようにconst
特有のあれこれがありませんでした。
というのもconst_trait_impl
, const_fn_floating_point_arithmetic
, const_mut_refs
, const_eval_limit
,といったfeature
を有効にしているからですが。
このあたりが早くstable
でもできるようになってくれると嬉しいです。
次回は複数のオブジェクトでワールドを作りレイが交差するかを判定します。