Renderer/src/main.rs

94 lines
2.8 KiB
Rust
Raw Normal View History

2022-04-20 18:58:58 +02:00
mod color;
2022-04-27 18:27:07 +02:00
mod hittable;
2022-05-04 18:21:48 +02:00
mod hittable_list;
2022-04-20 18:58:58 +02:00
mod ray;
2022-04-20 18:59:29 +02:00
mod vec3;
2022-05-04 18:21:48 +02:00
mod utility;
2022-04-20 18:58:58 +02:00
use ray::Ray;
use std::env;
use std::fs::File;
use std::io::BufWriter;
use std::io::Write;
2022-04-20 18:59:29 +02:00
use vec3::Color;
use vec3::Point3;
use vec3::Vec3;
2022-05-04 18:21:48 +02:00
use hittable::Hittable;
use hittable::Sphere;
use hittable_list::HittableList;
use hittable::HitRecord;
2022-04-20 18:58:58 +02:00
fn hit_sphere(center: &Point3, radius: f64, r: &Ray) -> f64 {
let oc = r.origin() - *center;
2022-04-27 18:27:07 +02:00
let a = r.direction().length_squared(); // gleiches Ergebnis wie Skalarprodukt
2022-04-20 18:58:58 +02:00
let b = 2.0 * Vec3::dot(oc, r.direction());
2022-04-27 18:27:07 +02:00
let c = oc.length_squared() - radius * radius;
2022-04-20 18:59:29 +02:00
let discriminant = b * b - 4.0 * a * c;
2022-04-20 18:58:58 +02:00
if discriminant < 0.0 {
return -1.0;
} else {
2022-04-20 18:59:29 +02:00
return (-b - discriminant.sqrt()) / (2.0 * a);
2022-04-20 18:58:58 +02:00
}
}
2022-05-04 18:21:48 +02:00
fn ray_color(r: &Ray, world: &HittableList) -> Color {
let mut rec = HitRecord::empty();
2022-04-20 18:59:29 +02:00
2022-05-04 18:21:48 +02:00
if world.hit(r, 0.0, f64::INFINITY, &mut rec) {
return 0.5 * (rec.normal + Color::new(1.0, 1.0, 1.0));
}
2022-04-20 18:58:58 +02:00
let unit_direction = r.direction();
2022-04-20 18:59:29 +02:00
let t = 0.5 * (unit_direction.y() + 1.0);
return (1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0);
2022-04-20 18:58:58 +02:00
}
2022-04-12 19:14:11 +02:00
2022-04-07 23:04:50 +02:00
fn main() {
2022-04-20 18:58:58 +02:00
// File
let mut default_file = "image.ppm";
// Image
let aspect_ratio = 16.0 / 9.0;
2022-05-04 18:21:48 +02:00
let image_width = 1000;
2022-04-20 18:58:58 +02:00
let image_height = (image_width as f64 / aspect_ratio) as u64;
2022-05-04 18:21:48 +02:00
// World
let mut world = HittableList::new();
world.add(Box::<Sphere>::new(Sphere::new(Point3::new(0.0, 0.0, -1.0), 0.5)));
world.add(Box::<Sphere>::new(Sphere::new(Point3::new(0.0, -100.5, -1.0), 100.0)));
2022-04-20 18:58:58 +02:00
// Camera
let viewport_height = 2.0;
let viewport_width = aspect_ratio * viewport_height;
let focal_length = 1.0;
2022-04-07 23:04:50 +02:00
2022-04-20 18:59:29 +02:00
let origin = Point3::new(0.0, 0.0, 0.0);
2022-04-20 18:58:58 +02:00
let horizontal = Vec3::new(viewport_width, 0.0, 0.0);
let vertical = Vec3::new(0.0, viewport_height, 0.0);
2022-04-20 18:59:29 +02:00
let lower_left_corner =
origin - horizontal / 2.0 - vertical / 2.0 - Vec3::new(0.0, 0.0, focal_length);
2022-04-20 18:58:58 +02:00
// Render
let args: Vec<String> = env::args().collect();
if args.len() > 1 && args[1] != "" {
default_file = &args[1];
}
let mut file = BufWriter::new(File::create(default_file).unwrap());
2022-04-20 18:59:29 +02:00
writeln!(&mut file, "P3\n{image_width} {image_height}\n255\n").unwrap();
2022-04-07 23:04:50 +02:00
2022-04-20 18:58:58 +02:00
for j in (0..image_height).rev() {
eprint!("\rScanlines remaining: {j:5}");
for i in 0..image_width {
2022-04-20 18:59:29 +02:00
let u = i as f64 / (image_width - 1) as f64;
let v = j as f64 / (image_height - 1) as f64;
let r = Ray::new(
origin,
lower_left_corner + u * horizontal + v * vertical - origin,
);
2022-05-04 18:21:48 +02:00
let pixel_color = ray_color(&r, &mut world);
2022-04-07 23:04:50 +02:00
2022-04-20 18:58:58 +02:00
color::write_color(&mut file, pixel_color);
2022-04-07 23:04:50 +02:00
}
}
eprintln!("\nDone!");
2022-04-20 18:59:29 +02:00
}