chore: hit record
This commit is contained in:
parent
89ad39b3e4
commit
11245af112
|
@ -4,7 +4,7 @@ use std::io::{BufWriter};
|
|||
use crate::hittable::HittableList;
|
||||
use crate::math_utils::clamp;
|
||||
use crate::ppm_writer::PPMWriter;
|
||||
use crate::types_defined::{Camera, Color, Point, Ray, Vec3};
|
||||
use crate::types_defined::{Camera, Color, HitRecord, Point, Ray, Vec3};
|
||||
use rand::rngs::ThreadRng;
|
||||
use rand::{Rng, thread_rng};
|
||||
|
||||
|
@ -89,11 +89,6 @@ impl<'a> Camera<'a> {
|
|||
);
|
||||
|
||||
self.ppm_file_writer.write(color.to_color());
|
||||
|
||||
|
||||
// content
|
||||
// img_content.push_str(&color_clamped.to_color_str().as_str());
|
||||
// img_content.push('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,11 +103,16 @@ impl<'a> Camera<'a> {
|
|||
}
|
||||
|
||||
// 限制出射光线的角度(0.001经验值)
|
||||
let hr = world.hit(&ray, 0.001, f32::MAX);
|
||||
if hr.t >= 0.0 {
|
||||
let hit_record = &mut HitRecord{
|
||||
t: 0.0,
|
||||
normal: Vec3::new(0.0, 0.0, 0.0),
|
||||
front_face: false,
|
||||
};
|
||||
let hit = world.hit(&ray, 0.001, f32::MAX, hit_record);
|
||||
if hit_record.t >= 0.0 {
|
||||
// diffuse normal vec
|
||||
let diffuse_vec = Vec3::random_unit();
|
||||
let lambertian_vec = diffuse_vec + hr.normal;
|
||||
let lambertian_vec = diffuse_vec + hit_record.normal;
|
||||
// 每次反射按0.5计算颜色(反射率 )
|
||||
return 0.5 * self.ray_color(&Ray::new(ray.point, lambertian_vec), depth - 1, world);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::types_defined::{HitRecord, Ray, Vec3};
|
||||
|
||||
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, hit_record: &mut HitRecord) -> bool;
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,22 +19,33 @@ impl HittableList {
|
|||
let _ = &self.objects.push(object);
|
||||
}
|
||||
|
||||
pub fn hit(&self, r: &Ray, t_min: f32, t_max: f32) -> HitRecord {
|
||||
pub fn hit(&self, r: &Ray, t_min: f32, t_max: f32, hit_record: &mut HitRecord) -> bool {
|
||||
|
||||
let mut hits = false;
|
||||
let mut closest_so_far = t_max;
|
||||
|
||||
let temp_hit_record = &mut HitRecord{
|
||||
t: 0.0,
|
||||
normal: Vec3::new(0.0, 0.0, 0.0),
|
||||
front_face: false,
|
||||
};
|
||||
|
||||
for object in &self.objects {
|
||||
let temp = object.hit(r, t_min, t_max);
|
||||
if temp.t >= 0.0 {
|
||||
return temp
|
||||
let hit = object.hit(r, t_min, closest_so_far, temp_hit_record);
|
||||
if hit {
|
||||
hits = true;
|
||||
closest_so_far = temp_hit_record.t;
|
||||
|
||||
hit_record.t = temp_hit_record.t;
|
||||
hit_record.front_face = temp_hit_record.front_face;
|
||||
hit_record.normal = temp_hit_record.normal;
|
||||
if temp_hit_record.t >= 0.0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
HitRecord {
|
||||
t: -1.0,
|
||||
normal: Vec3 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
},
|
||||
front_face: false,
|
||||
}
|
||||
|
||||
hits
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ fn camera_render() {
|
|||
width,
|
||||
16.0 / 9.0,
|
||||
2.0,
|
||||
Point::new(0.0, 0.0, 0.0),
|
||||
Point::new(0.0, 0.0, 1.0),
|
||||
Vec3::new(0.0, 0.0, -1.0),
|
||||
50,
|
||||
50,
|
||||
|
|
|
@ -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, hit_record: &mut HitRecord) -> bool {
|
||||
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);
|
||||
|
@ -28,19 +28,19 @@ impl hittable::Hittable for Sphere {
|
|||
if root <= t_min || root >= t_max {
|
||||
root = far;
|
||||
if root <= t_min || root >= t_max {
|
||||
root = -1.0;
|
||||
// hit_record.t = -1.0;
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let p = r.at(root);
|
||||
let normal = (p - self.center) / self.radius;
|
||||
HitRecord {
|
||||
t: root,
|
||||
// p,
|
||||
normal,
|
||||
// check if r.p inside(>=0) the sphere.
|
||||
front_face: r.direction.dot(normal) < 0.0,
|
||||
}
|
||||
|
||||
hit_record.t = root;
|
||||
hit_record.normal = normal;
|
||||
hit_record.front_face = r.direction.dot(normal) < 0.0;
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue