Fix hit determination inside a sphere
This commit is contained in:
parent
89a2333644
commit
46ec8663ff
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
*.ppm
|
*.ppm
|
||||||
.idea
|
.idea
|
||||||
*.iml
|
*.iml
|
||||||
|
.vscode/
|
||||||
|
@ -42,16 +42,16 @@ impl Hittable for Sphere {
|
|||||||
let discriminant = half_b * half_b - a * c;
|
let discriminant = half_b * half_b - a * c;
|
||||||
if discriminant < 0.0 { return None; }
|
if discriminant < 0.0 { return None; }
|
||||||
|
|
||||||
let sqrtd = f64::sqrt(discriminant);
|
let sqrtd = discriminant.sqrt();
|
||||||
let root = (-half_b - sqrtd) / a;
|
let mut root = (-half_b - sqrtd) / a;
|
||||||
if root < t_min || t_max < root {
|
if root < t_min || t_max < root {
|
||||||
let root = (-half_b + sqrtd) / a;
|
root = (-half_b + sqrtd) / a;
|
||||||
if root < t_min || t_max < root { return None; }
|
if root < t_min || t_max < root { return None; }
|
||||||
}
|
}
|
||||||
|
|
||||||
let point = ray.at(root);
|
let point = ray.at(root);
|
||||||
let normal = (point - self.center) / self.radius;
|
let normal = (point - self.center) / self.radius;
|
||||||
let front_face = ray.direction().dot(&normal) < 0.0;
|
let dot = ray.direction().dot(&normal);
|
||||||
|
let front_face = dot < 0.0;
|
||||||
let normal = if front_face { normal } else { -normal };
|
let normal = if front_face { normal } else { -normal };
|
||||||
Some(HitRecord {
|
Some(HitRecord {
|
||||||
point,
|
point,
|
||||||
|
@ -104,6 +104,7 @@ impl Scatterable for Dielectric {
|
|||||||
self.index_of_refraction
|
self.index_of_refraction
|
||||||
};
|
};
|
||||||
let unit_direction = ray.direction().unit_vector();
|
let unit_direction = ray.direction().unit_vector();
|
||||||
|
|
||||||
let cos_theta = ((-unit_direction).dot(&hit_record.normal)).min(1.0);
|
let cos_theta = ((-unit_direction).dot(&hit_record.normal)).min(1.0);
|
||||||
let sin_theta = (1.0 - cos_theta*cos_theta).sqrt();
|
let sin_theta = (1.0 - cos_theta*cos_theta).sqrt();
|
||||||
let cannot_refract = refraction_ratio * sin_theta > 1.0;
|
let cannot_refract = refraction_ratio * sin_theta > 1.0;
|
||||||
@ -112,12 +113,10 @@ impl Scatterable for Dielectric {
|
|||||||
|
|
||||||
if cannot_refract || reflectance > rng.gen::<f64>() {
|
if cannot_refract || reflectance > rng.gen::<f64>() {
|
||||||
let reflected = unit_direction.reflected(&hit_record.normal);
|
let reflected = unit_direction.reflected(&hit_record.normal);
|
||||||
let reflected = Vec3::new(-reflected.x(), reflected.y(), -reflected.z());
|
|
||||||
let scattered = Ray::new(hit_record.point, reflected);
|
let scattered = Ray::new(hit_record.point, reflected);
|
||||||
Some((Some(scattered), color))
|
Some((Some(scattered), color))
|
||||||
} else {
|
} else {
|
||||||
//let direction = unit_direction.refract(&hit_record.normal, refraction_ratio);
|
let direction = unit_direction.refract(&hit_record.normal, refraction_ratio);
|
||||||
let direction = unit_direction.refract_sort_of_works(&hit_record.normal, refraction_ratio);
|
|
||||||
let scattered = Ray::new(hit_record.point, direction);
|
let scattered = Ray::new(hit_record.point, direction);
|
||||||
Some((Some(scattered), color))
|
Some((Some(scattered), color))
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use crate::hittable::HitRecord;
|
|||||||
use crate::material::Scatterable;
|
use crate::material::Scatterable;
|
||||||
use crate::vec3::Point3;
|
use crate::vec3::Point3;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Ray {
|
pub struct Ray {
|
||||||
origin: Point3,
|
origin: Point3,
|
||||||
direction: Vec3
|
direction: Vec3
|
||||||
|
15
src/vec3.rs
15
src/vec3.rs
@ -84,21 +84,6 @@ impl Vec3 {
|
|||||||
let out_parallel = r * (*normal);
|
let out_parallel = r * (*normal);
|
||||||
out_perp + out_parallel
|
out_perp + out_parallel
|
||||||
}
|
}
|
||||||
pub fn refract_sort_of_works(&self, normal: &Vec3, etai_over_etat: f64) -> Vec3 {
|
|
||||||
let dot = (-(*self)).dot(normal);
|
|
||||||
let cos_theta = dot.min(1.0);
|
|
||||||
let out_perp = etai_over_etat * ((*self) + cos_theta * (*normal));
|
|
||||||
let inner = 1.0 - out_perp.length_squared();
|
|
||||||
let abs = inner.abs();
|
|
||||||
let r = -(abs.sqrt());
|
|
||||||
let out_parallel = r * (*normal);
|
|
||||||
// Why?
|
|
||||||
let mut res = out_perp + out_parallel;
|
|
||||||
res.x = -res.x;
|
|
||||||
//res.y = -res.y;
|
|
||||||
res.z = -res.z;
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user