Files
raytracing/src/main.rs
2026-04-15 13:57:43 +02:00

79 lines
2.3 KiB
Rust

#![feature(core_float_math)]
mod objects;
mod ray;
mod vec3;
use core::f32;
use std::cmp::max;
use crate::objects::hit::Hit;
use crate::objects::sphere::Sphere;
use crate::objects::traits::Hittable;
use crate::ray::Ray;
use crate::vec3::{Colour, Vec3};
use log::info;
use pretty_env_logger;
fn ray_colour<T: Hittable>(hittables: &Vec<T>, r: &Ray) -> Colour {
let closest = Hit::hit_list(hittables, r);
if let Some(hit) = closest {
let n = hit.n();
return 0.5 * Colour::new(n.x() + 1., n.y() + 1., n.z() + 1.);
}
// background
let unit_dir = r.dir().get_unit();
let a = 0.5 * (unit_dir.y() + 1.);
(1.0 - a) * Colour::new(1., 1., 1.) + a * Colour::new(0.5, 0.7, 1.0)
}
fn main() {
pretty_env_logger::init();
// setup objects
let mut objects = vec![Sphere::new(Vec3::new(0., 0., -1.), 0.5)];
objects.push(Sphere::new(Vec3::new(0., 0., -0.1), 0.01));
objects.push(Sphere::new(Vec3::new(0., -100.5, -1.), 100.));
let aspect_ratio = 16. / 9.;
let image_width = 400;
let image_height = max(1, (image_width as f32 / aspect_ratio) as u32);
//camera
let focal_length = 1.;
let viewport_height = 2.;
let viewport_width = viewport_height * (image_width as f32 / image_height as f32);
let camera_center = Vec3::nil();
//viewport
let viewport_u = Vec3::new(viewport_width as f32, 0., 0.);
let viewport_v = Vec3::new(0., -viewport_height as f32, 0.);
let pixel_delta_u = viewport_u / image_width as f32;
let pixel_delta_v = viewport_v / image_height as f32;
let viewport_upper_left =
camera_center - Vec3::new(0., 0., focal_length) - viewport_u / 2 - viewport_v / 2;
let pixel00_loc = viewport_upper_left + 0.5 * (pixel_delta_u + pixel_delta_v);
let mut imgbuf = image::ImageBuffer::new(image_width, image_height);
// render
for j in 0..image_height {
info!("{}\tScanlines remaining.", (image_height - j));
for i in 0..image_width {
let pixel_center = pixel00_loc + (i * pixel_delta_u) + (j * pixel_delta_v);
let ray_dir = pixel_center - camera_center;
let r = Ray::new(camera_center, ray_dir);
let pixel = imgbuf.get_pixel_mut(i, j);
*pixel = ray_colour(&objects, &r).output();
}
}
info!("Writing image file...");
imgbuf.save("output.png").unwrap();
}