Feat: Rudimentary dielectric... but broken
Dielectric material matching Raytracing in a Weekend book chapter 10.2. But it isn't right. The spheres turn into solid black holes. As I'm making the commit, I've found the problem. I'm separating it out so I can tag it and explore the code a bit more. See the step-by-step changes, and such.
This commit is contained in:
@@ -34,8 +34,8 @@ fn main() {
|
||||
// world
|
||||
|
||||
let mat_ground = Material::Lambertian{ albedo: Vec3::new(0.8, 0.8, 0.0) };
|
||||
let mat_center = Material::Lambertian{ albedo: Vec3::new(0.7, 0.3, 0.3) };
|
||||
let mat_left = Material::Metal{ albedo: Vec3::new(0.8, 0.8, 0.8), fuzz: 0.3 };
|
||||
let mat_center = Material::Dielectric { index_refraction: 1.5 };
|
||||
let mat_left = Material::Dielectric { index_refraction: 1.5 };
|
||||
let mat_right = Material::Metal{ albedo: Vec3::new(0.8, 0.6, 0.2), fuzz: 1.0 };
|
||||
|
||||
let mut world = HittableList::new();
|
||||
|
||||
@@ -11,8 +11,9 @@ use rand::distributions::Uniform;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Material{
|
||||
Lambertian{ albedo: Vec3 },
|
||||
Metal{ albedo:Vec3, fuzz: f32 },
|
||||
Lambertian { albedo: Vec3 },
|
||||
Metal { albedo:Vec3, fuzz: f32 },
|
||||
Dielectric { index_refraction: f32 },
|
||||
}
|
||||
|
||||
impl Material {
|
||||
@@ -58,6 +59,19 @@ impl Material {
|
||||
*attenuation = *albedo;
|
||||
return Vec3::dot(scattered.dir, rec.normal) > 0.0;
|
||||
},
|
||||
Material::Dielectric { index_refraction } => {
|
||||
*attenuation = Vec3::ones();
|
||||
let refraction_ratio = if rec.front_face { 1.0 / index_refraction } else { *index_refraction };
|
||||
|
||||
let unit_direction = Vec3::as_unit(&ray_in.dir);
|
||||
let refracted = Vec3::refract(unit_direction, rec.normal, refraction_ratio);
|
||||
|
||||
*scattered = Ray {
|
||||
orig: rec.p,
|
||||
dir: refracted
|
||||
};
|
||||
return true;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
41
src/vec3.rs
41
src/vec3.rs
@@ -87,23 +87,30 @@ impl Vec3{
|
||||
let g = (self.y * scale).sqrt();
|
||||
let b = (self.z * scale).sqrt();
|
||||
|
||||
let ir = (Vec3::clamp(r, 0.0, 0.999) * 256.0) as i32;
|
||||
let ig = (Vec3::clamp(g, 0.0, 0.999) * 256.0) as i32;
|
||||
let ib = (Vec3::clamp(b, 0.0, 0.999) * 256.0) as i32;
|
||||
let ir = (clamp(r, 0.0, 0.999) * 256.0) as i32;
|
||||
let ig = (clamp(g, 0.0, 0.999) * 256.0) as i32;
|
||||
let ib = (clamp(b, 0.0, 0.999) * 256.0) as i32;
|
||||
format!("{} {} {}", ir, ig, ib)
|
||||
}
|
||||
|
||||
pub fn near_zero(&self) -> bool {
|
||||
let epsilon: f32 = 1e-8;
|
||||
let epsilon: f32 = 1e-4;
|
||||
return
|
||||
self.x < epsilon &&
|
||||
self.y < epsilon &&
|
||||
self.z < epsilon
|
||||
self.x.abs() < epsilon &&
|
||||
self.y.abs() < epsilon &&
|
||||
self.z.abs() < epsilon
|
||||
}
|
||||
|
||||
pub fn reflect(v: Vec3, n: Vec3) -> Vec3 {
|
||||
return v - n * Vec3::dot(v, n) * 2.0;
|
||||
}
|
||||
|
||||
pub fn refract(uv: Vec3, n: Vec3, etai_over_etat: f32) -> Vec3 {
|
||||
let cos_theta = min(Vec3::dot(-uv, n), 1.0);
|
||||
let r_out_perp = (uv + n * cos_theta) * etai_over_etat;
|
||||
let r_out_parallel = n * -(1.0 - r_out_perp.length_squared()).abs().sqrt();
|
||||
r_out_perp + r_out_parallel
|
||||
}
|
||||
|
||||
pub fn dot(left: Vec3, right: Vec3) -> f32{
|
||||
left.x * right.x +
|
||||
@@ -124,15 +131,6 @@ impl Vec3{
|
||||
*v / len
|
||||
}
|
||||
|
||||
fn clamp(input: f32, min: f32, max: f32) -> f32 {
|
||||
if input < min {
|
||||
return min;
|
||||
} else if input > max {
|
||||
return max;
|
||||
} else {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Add for Vec3 {
|
||||
type Output = Vec3;
|
||||
@@ -281,6 +279,17 @@ impl Display for Vec3 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clamp(input: f32, lower: f32, upper: f32) -> f32 {
|
||||
min(max(input, lower), upper)
|
||||
}
|
||||
|
||||
pub fn min(a: f32, b: f32) -> f32 {
|
||||
if a < b { a } else { b }
|
||||
}
|
||||
|
||||
pub fn max(a: f32, b: f32) -> f32 {
|
||||
if a > b { a } else { b }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test{
|
||||
|
||||
Reference in New Issue
Block a user