WIP: Add final scene

This commit is contained in:
max.nuding 2022-07-11 15:35:09 +02:00
parent a552c4721f
commit a63e001edd
Failed to extract signature
2 changed files with 183 additions and 26 deletions

View File

@ -11,6 +11,7 @@ use rand::distributions::{Distribution, Uniform};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use crate::material::{Dielectric, DiffuseLight, Lambertian, Material, Metal};
use crate::aabb::Aabb;
use crate::bvh::BVH;
use crate::constant_medium::ConstantMedium;
use crate::cuboid::Cuboid;
use crate::image_texture::ImageTexture;
@ -42,7 +43,7 @@ mod isotropic;
// Image
const DEFAULT_ASPECT_RATIO: f64 = 3.0 / 2.0;
const IMAGE_WIDTH: usize = 600;
const IMAGE_WIDTH: usize = 800;
const SAMPLES_PER_PIXEL: i32 = 200;
const MAX_DEPTH: i32 = 50;
@ -603,9 +604,178 @@ fn random_scene() -> Scene {
}
}
fn next_week_final() -> Scene {
let ground = Arc::new(
Material::Lambertian(Lambertian::from(Color::new(0.48, 0.84, 0.53))));
let boxes_per_side = 20;
let mut rng = rand::thread_rng();
let box_range = Uniform::from(1.0..101.0);
let mut boxes1: HittableList = Vec::with_capacity(boxes_per_side*boxes_per_side);
for i in 0..boxes_per_side {
for j in 0..boxes_per_side {
let w = 100.0;
let x0 = -1000.0 + (i as f64)*w;
let z0 = -1000.0 + (j as f64)*w;
let y0 = 0.0;
let x1 = x0 + w;
let y1 = box_range.sample(&mut rng);
let z1 = z0 + w;
boxes1.push(Arc::new(Cuboid::new(
Vec3::new(x0, y0, z0),
Vec3::new(x1, y1, z1),
ground.clone()
)));
}
}
let mut world: HittableList = Vec::new();
world.push(Arc::new(BVH::new(boxes1, 0.0, 1.0)));
let light = Arc::new(
Material::DiffuseLight(DiffuseLight::from(Color::new(7.0, 7.0, 7.0))));
world.push(Arc::new(Rect2D::new(
Plane::XZ,
123.0,
423.0,
147.0,
412.0,
554.0,
light
)));
let moving_sphere_material = Arc::new(
Material::Lambertian(Lambertian::from(Color::new(0.7, 0.3, 0.1))));
let center1 = Point3::new(400.0, 400.0, 200.0);
world.push(Arc::new(MovableSphere::new(
center1,
center1 + Vec3::new(30.0, 0.0, 0.0),
50.0,
moving_sphere_material,
0.0,
1.0
)));
let glass = Arc::new(Material::Dielectric(Dielectric::new(1.5)));
world.push(Arc::new(Sphere::new(
Point3::new(260.0, 150.0, 45.0),
50.0,
glass.clone()
)));
world.push(Arc::new(Sphere::new(
Point3::new(0.0, 150.0, 145.0),
50.0,
Arc::new(
Material::Metal(Metal::new(Color::new(0.8, 0.8, 0.9), 1.0)))
)));
let boundary = Sphere::new(
Point3::new(360.0, 150.0, 145.0),
70.0,
glass.clone()
);
let boundary_clone = Sphere::new(
Point3::new(360.0, 150.0, 145.0),
70.0,
glass.clone()
);
world.push(Arc::new(boundary_clone));
world.push(Arc::new(
ConstantMedium::colored(
boundary,
Color::new(0.2, 0.4, 0.9),
0.2)));
let boundary = Sphere::new(
Point3::new(0.0, 0.0, 0.0),
5000.0,
glass.clone()
);
world.push(Arc::new(
ConstantMedium::colored(
boundary,
Color::new(1.0, 1.0, 1.0),
0.0001)));
let earth_material = Arc::new(Material::Lambertian(
Lambertian::textured(
Arc::new(ImageTexture::new("textures/earthmap.jpg")))));
world.push(Arc::new(Sphere::new(
Point3::new(400.0, 200.0, 400.0),
100.0,
earth_material
)));
let pertext = Arc::new(Material::Lambertian(Lambertian::textured(
Arc::new(NoiseTexture {
noise: Perlin::new(),
scale: 0.1
}))));
world.push(Arc::new(Sphere::new(
Point3::new(220.0, 280.0, 300.0),
100.0,
pertext
)));
let ns = 1000;
let mut boxes2: HittableList = Vec::with_capacity(ns);
let white = Arc::new(Material::Lambertian(
Lambertian::from(Color::new(0.73, 0.73, 0.73))));
/*
for _i in 0..ns {
world.push(Arc::new(
Translate::new(
Sphere::new(
Point3::random(0.0, 165.0),
10.0,
white.clone()
),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_at = Point3::new(278.0, 278.0, 0.0);
let focus_dist = 2.0;
let cam = Camera::new(
look_from,
look_at,
Vec3::new(0.0, 1.0, 0.0),
1.0,
40.0,
0.0,
focus_dist,
0.0,
1.0);
Scene {
world,
cam,
background: Color::default()
}
}
fn main() {
rayon::ThreadPoolBuilder::new().num_threads(3).build_global().unwrap(); // Enable, to reduce load
// World
let scene: u8 = 6;
let scene: u8 = 7;
let scene_setup = match scene {
0 => two_spheres(),
1 => two_perlin_spheres(),
@ -614,6 +784,7 @@ fn main() {
4 => simple_light(),
5 => cornell_box(),
6 => cornell_box_smoke(),
7 => next_week_final(),
_ => random_scene(),
};
@ -623,7 +794,7 @@ fn main() {
let image_height: usize = (IMAGE_WIDTH as f64 / scene_setup.cam.aspect_ratio()) as usize;
let mut pixels = vec![0; IMAGE_WIDTH * image_height * 3];
let bands: Vec<(usize, &mut [u8])> = pixels.chunks_mut(3).enumerate().collect();
//rayon::ThreadPoolBuilder::new().num_threads(3).build_global().unwrap(); // Enable, to reduce load
let count = Mutex::new(0);
bands.into_par_iter().for_each(|(i, pixel)| {
let row = image_height - (i / IMAGE_WIDTH) - 1;

View File

@ -18,31 +18,17 @@ impl<H: Hittable> Hittable for Translate<H> {
ray.origin() - self.offset,
ray.direction(),
ray.time());
match &self.hittable.hit(&moved_ray, t_min, t_max) {
Some(hit_record) => {
let mut hr = HitRecord {
point: hit_record.point + self.offset,
material: hit_record.material,
front_face: hit_record.front_face, // Maybe need to calc normal and front_face again?
normal: hit_record.normal,
t: hit_record.t,
u: hit_record.u,
v: hit_record.v
};
hr.normalized(ray);
Some(hr)
}
_ => None
}
self.hittable.hit(&moved_ray, t_min, t_max).map(|mut hr| {
hr.point += self.offset;
hr
})
}
fn bounding_box(&self, time0: f64, time1: f64) -> Option<Aabb> {
match &self.hittable.bounding_box(time0, time1) {
Some(bounding_box) => Some(Aabb {
minimum: bounding_box.minimum + self.offset,
maximum: bounding_box.maximum + self.offset,
}),
_ => None
}
self.hittable.bounding_box(time0, time1).map(|mut b| {
b.min += self.offset;
b.max += self.offset;
b
})
}
}