@@ 47,54 47,21 @@ fn main() {
let mut handle = stdout.lock();
// Image
- let aspect_ratio = 16.0 / 9.0;
- // let image_width = 400;
- let image_width = 1000;
- // let image_width = 1600;
+ let aspect_ratio = 3.0 / 2.0;
+ let image_width = 1200;
let image_height = (image_width as f64 / aspect_ratio) as i32;
- let samples_per_pixel = 50;
+ let samples_per_pixel = 500;
let max_depth = 50;
// World
- let mut world = HittableList::empty();
-
- let material_ground: MaterialPtr = Arc::new(Lambertian::new(Color::new(0.8, 0.8, 0.0)));
- let material_center: MaterialPtr = Arc::new(Lambertian::new(Color::new(0.1, 0.2, 0.5)));
- let material_left: MaterialPtr = Arc::new(Dielectric::new(1.5));
- let material_right: MaterialPtr = Arc::new(Metal::new(Color::new(0.8, 0.6, 0.2), 0.0));
-
- world.add(Arc::new(Sphere::new(
- Point3::new(0.0, -100.5, -1.0),
- 100.0,
- material_ground,
- )));
- world.add(Arc::new(Sphere::new(
- Point3::new(0.0, 0.0, -1.0),
- 0.5,
- material_center,
- )));
- world.add(Arc::new(Sphere::new(
- Point3::new(-1.0, 0.0, -1.0),
- 0.5,
- material_left.clone(),
- )));
- world.add(Arc::new(Sphere::new(
- Point3::new(-1.0, 0.0, -1.0),
- -0.4,
- material_left,
- )));
- world.add(Arc::new(Sphere::new(
- Point3::new(1.0, 0.0, -1.0),
- 0.5,
- material_right,
- )));
+ let world = random_scene();
// Camera
- let lookfrom = Point3::new(3., 3., 2.);
- let lookat = Point3::new(0., 0., -1.);
+ let lookfrom = Point3::new(13., 2., 3.);
+ let lookat = Point3::new(0., 0., 0.);
let vup = Vec3::new(0., 1., 0.);
- let dist_to_focus = (lookfrom - lookat).length();
- let aperture = 2.0;
+ let dist_to_focus = 10.0; //(lookfrom - lookat).length();
+ let aperture = 0.1;
let cam = Camera::new(
lookfrom,
lookat,
@@ 124,3 91,67 @@ fn main() {
}
eprintln!("\nDone!");
}
+
+fn random_scene() -> HittableList {
+ let mut world = HittableList::empty();
+
+ let ground_material: MaterialPtr = Arc::new(Lambertian::new(Color::new(0.5, 0.5, 0.5)));
+ world.add(Arc::new(Sphere::new(
+ Point3::new(0., -1000., 0.),
+ 1000.,
+ ground_material,
+ )));
+
+ for a in -11..11 {
+ for b in -11..11 {
+ let choose_mat = random_double();
+ let center = Point3::new(
+ a as f64 + 0.9 * random_double(),
+ 0.2,
+ b as f64 + 0.9 * random_double(),
+ );
+
+ if (center - Point3::new(4., 0.2, 0.)).length() > 0.9 {
+ if choose_mat < 0.8 {
+ // diffuse
+ let albedo = Color::random() * Color::random();
+ let sphere_material: MaterialPtr = Arc::new(Lambertian::new(albedo));
+ world.add(Arc::new(Sphere::new(center, 0.2, sphere_material)));
+ } else if choose_mat < 0.95 {
+ // metal
+ let albedo = Color::random_range(0.5..1.);
+ let fuzz = random_double_range(0f64..0.5);
+ let sphere_material: MaterialPtr = Arc::new(Metal::new(albedo, fuzz));
+ world.add(Arc::new(Sphere::new(center, 0.2, sphere_material)));
+ } else {
+ // glass
+ let sphere_material = Arc::new(Dielectric::new(1.5));
+ world.add(Arc::new(Sphere::new(center, 0.2, sphere_material)));
+ }
+ }
+ }
+ }
+
+ let material1 = Arc::new(Dielectric::new(1.5));
+ world.add(Arc::new(Sphere::new(
+ Point3::new(0., 1., 0.),
+ 1.0,
+ material1,
+ )));
+
+ let material2 = Arc::new(Lambertian::new(Color::new(0.4, 0.2, 0.1)));
+ world.add(Arc::new(Sphere::new(
+ Point3::new(-4., 1., 0.),
+ 1.0,
+ material2,
+ )));
+
+ let material3 = Arc::new(Metal::new(Color::new(0.7, 0.6, 0.5), 0.0));
+ world.add(Arc::new(Sphere::new(
+ Point3::new(4., 1., 0.),
+ 1.0,
+ material3,
+ )));
+
+ world
+}