From 5a77b92d9e6dc679931163b57a2b26965dec5192 Mon Sep 17 00:00:00 2001 From: dengqn Date: Sun, 3 Aug 2025 02:16:05 +0800 Subject: [PATCH] HittableList --- src/hittable.rs | 19 +++++++++++++++++-- src/image.rs | 17 +++++++++-------- src/sphere.rs | 14 +++++++++----- src/types_defined.rs | 6 +++++- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/hittable.rs b/src/hittable.rs index 765d700..162829f 100644 --- a/src/hittable.rs +++ b/src/hittable.rs @@ -1,5 +1,20 @@ use crate::types_defined::{HitRecord, Ray}; pub trait Hittable { - fn hit(self, r: &Ray, t_min: f32, t_max: f32) -> HitRecord; -} \ No newline at end of file + fn hit(&self, r: &Ray, t_min: f32, t_max: f32) -> HitRecord; +} + + +pub struct HittableList { + pub objects: Vec> +} +impl HittableList { + pub fn hit(&self, r: &Ray, t_min: f32, t_max: f32) -> Vec { + let mut records = vec![]; + for object in &self.objects { + records.push(object.hit(r, t_min, t_max)); + } + records + } +} + diff --git a/src/image.rs b/src/image.rs index a77b1d0..0c0b1cb 100644 --- a/src/image.rs +++ b/src/image.rs @@ -23,7 +23,7 @@ pub fn gen_ray_sphere_normal_ppm_p3(width: i32, height: i32, camera_center: Vec3 球 */ let _sphere_center = Point::new(0.0, 0.0, -1.0); - let sphere_radius = 0.5; + let sphere_radius = -0.5; let sphere = Sphere::new(_sphere_center, sphere_radius); // determind color @@ -43,15 +43,16 @@ ray color functions fn ray_color(r: &Ray, h: H) -> Color { let hr = h.hit(&r, 0.0, f32::MAX); if hr.t >= 0.0 { - let inter_point = hr.p; - // 单位向量 - let n = inter_point / inter_point.dot(inter_point); - // 法向量也是 -1~1 +1再x0.5让他落到颜色的区间 - // return 0.5 * (n - sphere_center + Point::new(1.0, 1.0, 1.0)) - return 0.5 * (hr.normal + Point::new(1.0, 1.0, 1.0)) + let normal_color = 0.5 * (hr.normal + Point::new(1.0, 1.0, 1.0)); + return if hr.front_face { + normal_color + } else { + Color::new(1.0, 1.0, 1.0) - normal_color + } } // v / |v| let unit_direction = r.direction / r.direction.length(); let a = 0.5*(unit_direction.y + 1.0); - return (1.0-a)*Color::new(1.0, 1.0, 1.0) + a*Color::new(0.5, 0.7, 1.0); + // return background color. + (1.0-a)*Color::new(1.0, 1.0, 1.0) + a*Color::new(0.5, 0.7, 1.0) } \ No newline at end of file diff --git a/src/sphere.rs b/src/sphere.rs index a63d907..b1fc8e5 100644 --- a/src/sphere.rs +++ b/src/sphere.rs @@ -11,7 +11,7 @@ impl Sphere { } impl hittable::Hittable for Sphere { - fn hit(self, r: &Ray, t_min: f32, t_max: f32) -> HitRecord { + fn hit(&self, r: &Ray, t_min: f32, t_max: f32) -> HitRecord { let a: f32 = r.direction.length_squared(); let h = r.direction.dot(self.center - r.point); // let b = -2.0 * r.direction.dot(sphere_center - r.point); @@ -19,7 +19,7 @@ impl hittable::Hittable for Sphere { let discriminant = h * h - a * c; - // // 两个焦点 + // // 两个交点 let disc_sqrt = discriminant.sqrt(); let near = (h - disc_sqrt) / a; let far = (h + disc_sqrt) / a; @@ -31,11 +31,15 @@ impl hittable::Hittable for Sphere { root = -1.0; } } - + + let p = r.at(root); + let normal = (p - self.center) / self.radius; HitRecord { t: root, - p: r.at(root), - normal: r.at(root) - self.center, + // p, + normal, + // check if r.p inside(>=0) the sphere. + front_face: r.direction.dot(normal) < 0.0, } } } diff --git a/src/types_defined.rs b/src/types_defined.rs index 5557cc7..b7de5b4 100644 --- a/src/types_defined.rs +++ b/src/types_defined.rs @@ -1,6 +1,8 @@ /* * [3] */ +use crate::hittable::Hittable; + #[derive(Debug, Clone, Copy, PartialEq)] pub struct Vec3 { pub x: f32, @@ -21,11 +23,13 @@ pub struct Ray { pub struct HitRecord { pub t: f32, - pub p: Vec3, + // pub p: Vec3, pub normal: Vec3, + pub front_face: bool, } + /* ///////////// // for test