HittableList
This commit is contained in:
parent
63ccb552fd
commit
5a77b92d9e
|
@ -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;
|
||||
}
|
||||
fn hit(&self, r: &Ray, t_min: f32, t_max: f32) -> HitRecord;
|
||||
}
|
||||
|
||||
|
||||
pub struct HittableList {
|
||||
pub objects: Vec<Box<dyn Hittable>>
|
||||
}
|
||||
impl HittableList {
|
||||
pub fn hit(&self, r: &Ray, t_min: f32, t_max: f32) -> Vec<HitRecord> {
|
||||
let mut records = vec![];
|
||||
for object in &self.objects {
|
||||
records.push(object.hit(r, t_min, t_max));
|
||||
}
|
||||
records
|
||||
}
|
||||
}
|
||||
|
||||
|
|
17
src/image.rs
17
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<H: Hittable>(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)
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue