Skip to content

Commit

Permalink
[none] Create random balls in parallel
Browse files Browse the repository at this point in the history
- Use rayon par_iter to create the random balls
using random material.
- Extend worlds to add the balls

%SOFTWARE
  • Loading branch information
soumyasen1809 committed Aug 16, 2024
1 parent 489cc21 commit 9cb1939
Showing 1 changed file with 50 additions and 35 deletions.
85 changes: 50 additions & 35 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ use lib::utilities::{
point::Point3,
vector3::Vector3,
};
use rayon::prelude::*;

const NUMBER_BALLS: i32 = 5;

const ASPECT_RATIO: f64 = 16.0 / 9.0;
const IMAGE_WIDTH: i32 = 1600;
const IMAGE_WIDTH: i32 = 800;
const SAMPLES_PER_PIXEL: i32 = 200;
const MAX_DEPTH: i32 = 50;
const VERTICAL_FOV: f64 = 40.0;
Expand All @@ -32,40 +33,54 @@ fn main() {
)));

// Scene - small balls (random)
for x_index in -NUMBER_BALLS..NUMBER_BALLS {
for y_index in -NUMBER_BALLS..NUMBER_BALLS {
let choose_material_random: f64 = rand::thread_rng().r#gen::<f64>();
let center = Point3::new(
(x_index as f64) + (0.9 * rand::thread_rng().r#gen::<f64>()),
0.2,
(y_index as f64) + (0.9 * rand::thread_rng().r#gen::<f64>()),
);
if choose_material_random < 0.6 {
// Lambertian
let material_lambertian = Box::new(Lambertian::new(Color::new(
rand::thread_rng().r#gen::<f64>(),
rand::thread_rng().r#gen::<f64>(),
rand::thread_rng().r#gen::<f64>(),
)));
world.push(Box::new(Sphere::new(center, 0.2, material_lambertian)));
} else if choose_material_random < 0.85 {
// Metal
let material_metal = Box::new(Metal::new(
Color::new(
rand::thread_rng().r#gen::<f64>(),
rand::thread_rng().r#gen::<f64>(),
rand::thread_rng().r#gen::<f64>(),
),
rand::thread_rng().r#gen::<f64>(),
));
world.push(Box::new(Sphere::new(center, 0.2, material_metal)));
} else {
// Glass
let material_glass = Box::new(Dielectric::new(1.33));
world.push(Box::new(Sphere::new(center, 0.2, material_glass)));
}
}
}
let spheres_scene: Vec<Box<dyn Hittable>> = (-NUMBER_BALLS..NUMBER_BALLS)
.into_par_iter()
.flat_map(|x_index| {
(-NUMBER_BALLS..NUMBER_BALLS)
.into_par_iter()
.map(|y_index| {
let choose_material_random: f64 = rand::thread_rng().r#gen::<f64>();
let center = Point3::new(
(x_index as f64) + (0.9 * rand::thread_rng().r#gen::<f64>()),
0.2,
(y_index as f64) + (0.9 * rand::thread_rng().r#gen::<f64>()),
);
if choose_material_random < 0.4 {
// Lambertian
let material_lambertian = Box::new(Lambertian::new(Color::new(
rand::thread_rng().r#gen::<f64>(),
rand::thread_rng().r#gen::<f64>(),
rand::thread_rng().r#gen::<f64>(),
)));
return Box::new(Sphere::new(center, 0.2, material_lambertian))
as Box<dyn Hittable>;
} else if choose_material_random < 0.8 {
// Metal
let material_metal = Box::new(Metal::new(
Color::new(
rand::thread_rng().r#gen::<f64>(),
rand::thread_rng().r#gen::<f64>(),
rand::thread_rng().r#gen::<f64>(),
),
rand::thread_rng().r#gen::<f64>(),
));
return Box::new(Sphere::new(center, 0.2, material_metal))
as Box<dyn Hittable>;
} else {
// Glass
let material_glass = Box::new(Dielectric::new(1.33));
return Box::new(Sphere::new(center, 0.2, material_glass))
as Box<dyn Hittable>;
}
})
.collect::<Vec<Box<dyn Hittable>>>()
})
.collect();

world.extend(spheres_scene);
// If you don't need to use spheres_scene after pushing its contents to world, you can move the entire vector.
// Explanation: world.extend(spheres_scene) moves the contents of spheres_scene into world. The extend method consumes the vector, avoiding the need for cloning or referencing, and effectively transfers ownership of each Box<dyn Hittable> to world.
// Use moving (via extend) if you want to transfer ownership and don't need to use spheres_scene afterward, which is more efficient because it avoids unnecessary duplication.

// Scene - big balls with Glass material
let material_glass = Box::new(Dielectric::new(1.0 / 1.55));
Expand Down

0 comments on commit 9cb1939

Please sign in to comment.