54 lines
1.6 KiB
Rust
54 lines
1.6 KiB
Rust
extern crate rand;
|
|
extern crate rtiow;
|
|
|
|
use rand::Rng;
|
|
|
|
use rtiow::camera::Camera;
|
|
use rtiow::hitable::Hit;
|
|
use rtiow::hitable_list::HitableList;
|
|
use rtiow::ray::Ray;
|
|
use rtiow::sphere::Sphere;
|
|
use rtiow::vec3::Vec3;
|
|
|
|
fn color(r: Ray, world: &Hit) -> Vec3 {
|
|
if let Some(rec) = world.hit(r, 0., std::f32::MAX) {
|
|
return (rec.normal + 1.) * 0.5;
|
|
}
|
|
|
|
// No hit, choose color from background.
|
|
let unit_direction = r.direction().unit_vector();
|
|
let t = 0.5 * (unit_direction.y + 1.);
|
|
Vec3::new(1., 1., 1.) * (1. - t) + Vec3::new(0.5, 0.7, 1.) * t
|
|
}
|
|
|
|
fn main() -> Result<(), std::io::Error> {
|
|
let mut rng = rand::thread_rng();
|
|
let nx = 200;
|
|
let ny = 100;
|
|
let ns = 100;
|
|
println!("P3\n{} {}\n255", nx, ny);
|
|
let objects = vec![
|
|
Sphere::new(Vec3::new(0., 0., -1.), 0.5),
|
|
Sphere::new(Vec3::new(0., -100.5, -1.), 100.),
|
|
];
|
|
let cam = Camera::new2x1();
|
|
let world = HitableList::new(objects.iter().map(|o| o).collect());
|
|
for j in (0..ny).rev() {
|
|
for i in 0..nx {
|
|
let mut col: Vec3 = Default::default();
|
|
for _ in 0..ns {
|
|
let u = (rng.gen_range::<f32>(0., 1.) + i as f32) / nx as f32;
|
|
let v = (rng.gen_range::<f32>(0., 1.) + j as f32) / ny as f32;
|
|
let r = cam.get_ray(u, v);
|
|
col = col + color(r, &world);
|
|
}
|
|
col = col / ns as f32;
|
|
let ir = (255.99 * col[0]) as u32;
|
|
let ig = (255.99 * col[1]) as u32;
|
|
let ib = (255.99 * col[2]) as u32;
|
|
println!("{} {} {}", ir, ig, ib);
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|