Fix bounding box and BVH

This commit is contained in:
Max Nuding 2022-07-11 20:47:18 +02:00
parent a0eda53be1
commit 526e92f582
Signed by: phlaym
GPG Key ID: 0AAD39863E09DC48
3 changed files with 33 additions and 63 deletions

View File

@ -20,9 +20,7 @@ impl Default for Aabb {
} }
impl Aabb { impl Aabb {
pub fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> bool { pub fn hit(&self, ray: &Ray, mut t_min: f64, mut t_max: f64) -> bool {
let mut t_min = t_min;
let mut t_max = t_max;
for a in 0..3 { for a in 0..3 {
let inv_d = 1.0 / ray.direction()[a]; let inv_d = 1.0 / ray.direction()[a];
let mut t0 = (self.minimum[a] - ray.origin()[a]) * inv_d; let mut t0 = (self.minimum[a] - ray.origin()[a]) * inv_d;
@ -42,11 +40,11 @@ impl Aabb {
let minimum = Point3::new( let minimum = Point3::new(
self.minimum.x().min(other.minimum.x()), self.minimum.x().min(other.minimum.x()),
self.minimum.y().min(other.minimum.y()), self.minimum.y().min(other.minimum.y()),
self.minimum.y().min(other.minimum.z())); self.minimum.z().min(other.minimum.z()));
let maximum = Point3::new( let maximum = Point3::new(
self.maximum.x().max(other.maximum.x()), self.maximum.x().max(other.maximum.x()),
self.maximum.y().max(other.maximum.y()), self.maximum.y().max(other.maximum.y()),
self.maximum.y().max(other.maximum.z())); self.maximum.z().max(other.maximum.z()));
Aabb {minimum, maximum} Aabb {minimum, maximum}
} }
} }

View File

@ -83,10 +83,7 @@ impl Hittable for BVH {
let hit_left = left.hit(ray, t_min, t_max); let hit_left = left.hit(ray, t_min, t_max);
if let Some(hl) = &hit_left { t_max = hl.t }; if let Some(hl) = &hit_left { t_max = hl.t };
let hit_right = right.hit(ray, t_min, t_max); let hit_right = right.hit(ray, t_min, t_max);
match hit_left { if hit_right.is_some() { hit_right } else { hit_left }
Some(hit_left) => Some(hit_left),
_ => hit_right
}
} }
} }
} }

View File

@ -43,8 +43,8 @@ mod isotropic;
// Image // Image
const DEFAULT_ASPECT_RATIO: f64 = 3.0 / 2.0; const DEFAULT_ASPECT_RATIO: f64 = 3.0 / 2.0;
const IMAGE_WIDTH: usize = 800; const IMAGE_WIDTH: usize = 1600;
const SAMPLES_PER_PIXEL: i32 = 200; const SAMPLES_PER_PIXEL: i32 = 1_000;
const MAX_DEPTH: i32 = 50; const MAX_DEPTH: i32 = 50;
struct Scene { struct Scene {
@ -643,6 +643,7 @@ fn next_week_final() -> Scene {
light light
))); )));
// Moving Sphere
let moving_sphere_material = Arc::new( let moving_sphere_material = Arc::new(
Material::Lambertian(Lambertian::from(Color::new(0.7, 0.3, 0.1)))); Material::Lambertian(Lambertian::from(Color::new(0.7, 0.3, 0.1))));
let center1 = Point3::new(400.0, 400.0, 200.0); let center1 = Point3::new(400.0, 400.0, 200.0);
@ -656,11 +657,15 @@ fn next_week_final() -> Scene {
))); )));
let glass = Arc::new(Material::Dielectric(Dielectric::new(1.5))); let glass = Arc::new(Material::Dielectric(Dielectric::new(1.5)));
// Glass
world.push(Arc::new(Sphere::new( world.push(Arc::new(Sphere::new(
Point3::new(260.0, 150.0, 45.0), Point3::new(260.0, 150.0, 45.0),
50.0, 50.0,
glass.clone() glass.clone()
))); )));
// Metal sphere
world.push(Arc::new(Sphere::new( world.push(Arc::new(Sphere::new(
Point3::new(0.0, 150.0, 145.0), Point3::new(0.0, 150.0, 145.0),
50.0, 50.0,
@ -694,6 +699,7 @@ fn next_week_final() -> Scene {
Color::new(1.0, 1.0, 1.0), Color::new(1.0, 1.0, 1.0),
0.0001))); 0.0001)));
// Earth
let earth_material = Arc::new(Material::Lambertian( let earth_material = Arc::new(Material::Lambertian(
Lambertian::textured( Lambertian::textured(
Arc::new(ImageTexture::new("textures/earthmap.jpg"))))); Arc::new(ImageTexture::new("textures/earthmap.jpg")))));
@ -703,6 +709,7 @@ fn next_week_final() -> Scene {
earth_material earth_material
))); )));
// Gray sphere
let pertext = Arc::new(Material::Lambertian(Lambertian::textured( let pertext = Arc::new(Material::Lambertian(Lambertian::textured(
Arc::new(NoiseTexture { Arc::new(NoiseTexture {
noise: Perlin::new(), noise: Perlin::new(),
@ -710,7 +717,7 @@ fn next_week_final() -> Scene {
})))); }))));
world.push(Arc::new(Sphere::new( world.push(Arc::new(Sphere::new(
Point3::new(220.0, 280.0, 300.0), Point3::new(220.0, 280.0, 300.0),
100.0, 80.0,
pertext pertext
))); )));
@ -718,38 +725,29 @@ fn next_week_final() -> Scene {
let mut boxes2: HittableList = Vec::with_capacity(ns); let mut boxes2: HittableList = Vec::with_capacity(ns);
let white = Arc::new(Material::Lambertian( let white = Arc::new(Material::Lambertian(
Lambertian::from(Color::new(0.73, 0.73, 0.73)))); Lambertian::from(Color::new(0.73, 0.73, 0.73))));
/*
for _i in 0..ns { for _i in 0..ns {
world.push(Arc::new( let sphere = Sphere::new(
Point3::random(0.0, 165.0),
10.0,
white.clone()
);
boxes2.push(Arc::new(sphere));
}
world.push(
Arc::new(
Translate::new( Translate::new(
Sphere::new( RotateY::new(
Point3::random(0.0, 165.0), BVH::new(boxes2, 0.0, 1.0),
10.0, 15.0
white.clone() ),
),Vec3::new(-100.0, 270.0, 395.0)) Vec3::new(-100.0, 270.0, 395.0)
));
}
*/
for _i in 0..ns {
boxes2.push(Arc::new(
Sphere::new(
Point3::random(0.0, 165.0),
10.0,
white.clone()
) )
)); )
} );
let boxes2_bvh = BVH::new(boxes2, 0.0, 1.0);
//let rotated_bvh = RotateY::new(boxes2_bvh, 0.0);
//let rotated_bvh = RotateY::new(boxes2_bvh, 15.0);
//let translated_bvh = Translate::new(rotated_bvh, Vec3::new(-100.0, 270.0, 395.0));
let translated_bvh = Translate::new(boxes2_bvh, Vec3::new(-100.0, 270.0, 395.0));
world.push(Arc::new(translated_bvh));
let look_from = Point3::new(478.0, 278.0, -600.0); let look_from = Point3::new(478.0, 278.0, -600.0);
let look_at = Point3::new(278.0, 278.0, 0.0); let look_at = Point3::new(278.0, 278.0, 0.0);
let focus_dist = 2.0; let focus_dist = 2.0;
@ -773,7 +771,7 @@ fn next_week_final() -> Scene {
} }
fn main() { fn main() {
rayon::ThreadPoolBuilder::new().num_threads(3).build_global().unwrap(); // Enable, to reduce load //rayon::ThreadPoolBuilder::new().num_threads(3).build_global().unwrap(); // Enable, to reduce load
// World // World
let scene: u8 = 7; let scene: u8 = 7;
let scene_setup = match scene { let scene_setup = match scene {
@ -825,26 +823,3 @@ fn main() {
PNG::write("imc.png", &pixels, IMAGE_WIDTH, image_height).expect("Error writing image: {}"); PNG::write("imc.png", &pixels, IMAGE_WIDTH, image_height).expect("Error writing image: {}");
eprintln!("\nDone. Time: {}ms", start.elapsed().as_millis()); eprintln!("\nDone. Time: {}ms", start.elapsed().as_millis());
} }
fn world_bounding_box(time0: f64, time1: f64, world: &HittableList) -> Option<Aabb> {
if world.is_empty() {
return None;
}
let mut is_first = true;
let mut output_box: Aabb = Aabb {
minimum: Point3::default(),
maximum: Point3::default()
};
for object in world {
if let Some(bb) = object.bounding_box(time0, time1) {
output_box = match is_first {
true => bb,
false => output_box.surrounding(&bb)
};
is_first = false;
} else {
return None;
}
}
Some(output_box)
}