83 lines
2.3 KiB
Rust
83 lines
2.3 KiB
Rust
pub mod camera;
|
|
pub mod display;
|
|
pub mod hit;
|
|
pub mod ppm_format;
|
|
mod ray;
|
|
pub mod shapes;
|
|
mod vec;
|
|
|
|
use std::io::{stderr, Write};
|
|
|
|
use hit::Hit;
|
|
use rand::Rng;
|
|
use ray::Ray;
|
|
use vec::{Color, Point3, Vec3};
|
|
|
|
use crate::{camera::Camera, hit::World, ppm_format::Header, shapes::sphere::Sphere};
|
|
|
|
fn ray_color(r: &Ray, world: &World) -> Color {
|
|
if let Some(rec) = world.hit(r, 0.0, f64::INFINITY) {
|
|
0.5 * (rec.normal + Color::new(1.0, 1.0, 1.0))
|
|
} else {
|
|
let unit_direction = r.direction().normalized();
|
|
let t = 0.5 * (unit_direction.y() + 1.0);
|
|
(1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0)
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let xyz = "1280x720@60";
|
|
let display_info = display::parse_display_string(xyz).unwrap();
|
|
|
|
const SAMPLES_PER_PIXEL: u64 = 8;
|
|
|
|
// World
|
|
let mut world = World::new();
|
|
world.push(Box::new(Sphere::new(Point3::new(0.0, 0.0, -1.0), 0.5)));
|
|
world.push(Box::new(Sphere::new(Point3::new(0.0, -100.5, -1.0), 100.0)));
|
|
|
|
// Camera
|
|
let cam = Camera::new();
|
|
|
|
let header = Header {
|
|
ppm_format: ppm_format::PpmFormat::P3,
|
|
width: display_info.width,
|
|
height: display_info.height,
|
|
max_color_value: 255,
|
|
};
|
|
println!("{}", header);
|
|
|
|
use std::time::Instant;
|
|
let now = Instant::now();
|
|
|
|
// Code block to measure.
|
|
let mut rng = rand::thread_rng();
|
|
{
|
|
for j in (0..display_info.height).rev() {
|
|
eprint!("\rScanlines remaining: {:3}", display_info.height - j - 1);
|
|
stderr().flush().unwrap();
|
|
|
|
for i in 0..display_info.width {
|
|
let mut pixel_color = Color::new(0.0, 0.0, 0.0);
|
|
for _ in 0..SAMPLES_PER_PIXEL {
|
|
let random_u: f64 = rng.gen();
|
|
let random_v: f64 = rng.gen();
|
|
|
|
let u = ((i as f64) + random_u) / ((display_info.width - 1) as f64);
|
|
let v = ((j as f64) + random_v) / ((display_info.height - 1) as f64);
|
|
|
|
let r = cam.get_ray(u, v);
|
|
pixel_color += ray_color(&r, &world);
|
|
}
|
|
|
|
println!("{}", pixel_color.format_color(SAMPLES_PER_PIXEL));
|
|
}
|
|
}
|
|
|
|
let elapsed = now.elapsed();
|
|
eprintln!("\nElapsed: {:.2?}", elapsed);
|
|
}
|
|
|
|
eprintln!("\nDone.");
|
|
}
|