Material references... but bad ordering

It looks like I messed up the preference for the HitRecords. The
geometry bounces correctly, but the record that sticks is not
necessarily the one closest to the camera.
This commit is contained in:
2023-09-22 18:21:12 -07:00
parent 4ce43e12af
commit bdc396accf
4 changed files with 17 additions and 28 deletions

BIN
hitrecord_misordering.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

View File

@@ -134,7 +134,7 @@ fn random_scene(srng: &mut SmallRng) -> Hittable {
let mat_ground = Material::Lambertian { albedo: Vec3::new(0.5, 0.5, 0.5) };
let mut world = Hittable::HittableList { hittables : Vec::<Hittable>::new() };
world.push( Hittable::Sphere { center: Vec3::new(0.0, -1000.0, 0.0), radius: 1000.0, material: Some(mat_ground) });
world.push( Hittable::Sphere { center: Vec3::new(0.0, -1000.0, 0.0), radius: 1000.0, material: mat_ground });
let distrib_zero_one = Uniform::new(0.0, 1.0);
for a in -11..11 {
@@ -155,7 +155,7 @@ fn random_scene(srng: &mut SmallRng) -> Hittable {
Hittable::Sphere {
center,
radius: 0.2,
material: Some(sphere_material),
material: sphere_material,
}
);
} else if choose_mat < 0.95 {
@@ -170,7 +170,7 @@ fn random_scene(srng: &mut SmallRng) -> Hittable {
Hittable::Sphere {
center,
radius: 0.2,
material: Some(material),
material: material,
}
);
} else {
@@ -180,7 +180,7 @@ fn random_scene(srng: &mut SmallRng) -> Hittable {
Hittable::Sphere{
center,
radius: 0.2,
material: Some(material),
material: material,
}
);
@@ -193,21 +193,21 @@ fn random_scene(srng: &mut SmallRng) -> Hittable {
world.push( Hittable::Sphere{
center: Vec3::new(0.0, 1.0, 0.0),
radius: 1.0,
material: Some(material1)
material: material1
});
let material2 = Material::Lambertian { albedo: Vec3::new(0.4, 0.2, 0.1) };
world.push( Hittable::Sphere {
center: Vec3::new(-4.0, 1.0, 0.0),
radius: 1.0,
material: Some(material2)
material: material2
});
let material3 = Material::Metal { albedo: Vec3::new(0.7, 0.6, 0.5), fuzz: 0.0 };
world.push( Hittable::Sphere {
center: Vec3::new(4.0, 1.0, 0.0),
radius: 1.0,
material: Some(material3)
material: material3
});
return world;

View File

@@ -65,14 +65,9 @@ fn ray_color(r: Ray, world: &Hittable, depth: u32, srng: &mut SmallRng, distrib:
dir: Vec3::zero()
};
let mut attenuation = Vec3::zero();
match rec.material {
Some(mat) => {
if mat.scatter(r, rec, &mut attenuation, &mut scattered, srng) {
if rec.material.scatter(r, &rec, &mut attenuation, &mut scattered, srng) {
return attenuation * ray_color(scattered, world, depth-1, srng, distrib);
};
},
None => return Vec3::zero(),
}
}
let unitdir = Vec3::as_unit(r.dir);

View File

@@ -8,7 +8,7 @@ use rand::distributions::Uniform;
pub struct HitRecord{
pub p: Vec3,
pub normal: Vec3,
pub material: Option<Material>,
pub material: Material,
pub t: f32,
pub front_face: bool,
}
@@ -22,7 +22,7 @@ impl HitRecord{
#[derive (Clone)]
pub enum Hittable {
Sphere { center: Vec3, radius: f32, material: Option<Material> },
Sphere { center: Vec3, radius: f32, material: Material },
HittableList { hittables: Vec<Hittable> }
}
@@ -30,23 +30,17 @@ impl Hittable {
pub fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
match self {
Hittable::HittableList { hittables } => {
let mut might_return = HitRecord {
p: Vec3::zero(),
normal: Vec3::zero(),
material: None,
t: t_max,
front_face: false,
};
let mut might_return: Option<HitRecord> = None;
let mut hit_anything = false;
for item in hittables {
if let Some(record) = item.hit(r, t_min, might_return.t){
if let Some(record) = item.hit(r, t_min, t_max){
hit_anything = true;
might_return = record;
might_return = Some(record);
}
}
if hit_anything{
return Some(might_return);
return might_return;
} else { return None; }
}
@@ -102,7 +96,7 @@ impl Material {
pub fn scatter(
&self,
ray_in: Ray,
rec: HitRecord,
rec: &HitRecord,
attenuation: &mut Vec3,
scattered: &mut Ray,
srng: &mut SmallRng,