123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- use std::path::Path;
- mod random;
- mod geometry;
- mod image;
- mod mesh;
- mod bsdf;
- mod bvh;
- use crate::geometry::Vec3;
- use crate::random::RNG;
- use crate::mesh::Mesh;
- use crate::geometry::Ray;
- use crate::image::Image;
- use crate::bvh::BVH;
- // ┏┳┓┏━┓╻┏┓╻
- // ┃┃┃┣━┫┃┃┗┫
- // ╹ ╹╹ ╹╹╹ ╹
- fn print_bvh_stats(bvh: &BVH) {
- print!("Triangles in leaf: ");
- fn discover_leaves(bvh: &BVH) {
- match bvh {
- BVH::Leaf(_, v) => {
- print!("{} ", v.len());
- },
- BVH::Node(_, left, right) => {
- discover_leaves(left);
- discover_leaves(right);
- }
- }
- }
- discover_leaves(bvh);
- println!();
- }
- fn main() {
- let m = Mesh::load("benchmarks/suzanne.obj");
- println!("First vertex: {}", m[0].vertices[m[0].vertices.len() - 1]);
- println!("Building BVH…");
- let bvh = BVH::from(&m, 12);
- println!("BVH created");
- print_bvh_stats(&bvh);
- println!("Triangle center: {}", m[0].faces[0].center);
- let mut rng = RNG::create();
- // Generate camera rays
- // Camera has origin 0,0 and will look downwards on z axis.
- const SPP : u16 = 1;
- const WIDTH : u16 = 256;
- const HEIGHT : u16 = 256;
- const D: f32 = 1.0; // distance of image plane to camera origin
- const FOV : f32 = 80.0; // opening angle of camera
- let mut img = Image::new(WIDTH, HEIGHT);
- let mut intersection_counts = vec!();
- for x in 0..WIDTH {
- for y in 0..HEIGHT {
- let target_x = (f32::from(x) / f32::from(WIDTH) - 0.5) * (FOV / 2.0).tan() * D;
- let target_y = (f32::from(y) / f32::from(HEIGHT) - 0.5) * (FOV / 2.0).tan() * D;
- let pixel = img.mod_pixel(x.into(), y.into());
- let mut r = Ray {
- origin: Vec3 {
- x: 0.0,
- y: 0.0,
- z: 0.0,
- },
- direction: Vec3 {
- x: target_x,
- y: target_y,
- z: D
- },
- n_inv: Vec3::new(0.0, 0.0, 0.0)
- };
- r.calc_n_inv();
- //println!("Shooting ray {} {} {}", target_x, target_y, D);
-
- for _ in 0..SPP {
- let (count, intersection) = bvh.intersect(&r, 0);
- intersection_counts.push(count);
- if intersection.is_some() {
- //println!("HIT! {}", r.direction);
- }
- let color = intersection
- .map(|i| Vec3::new(255.0, 255.0, 0.0))
- .unwrap_or(Vec3::new(0.0, 0.0, 0.0));
- //let sample : Vec3= 255.0 / f32::from(SPP) * raytrace(&r);
- //println!("{} --> {}", r.direction, sample);
- *pixel += color;
- }
- }
- if x % (WIDTH / 100) == 0 {
- println!("Progress: {:.0}%", 100.0 * f32::from(x) / f32::from(WIDTH));
- }
- }
- let intersections_per_ray = (intersection_counts.iter().sum::<usize>() as f64) / (f64::from((WIDTH as u32)* (HEIGHT as u32)* (SPP as u32)));
- //println!("Intersections per ray: {}", intersections_per_ray);
- println!("Intersections per ray: {}", intersections_per_ray);
- img.save_bmp(&Path::new("Render.bmp")).expect("Failed to save rendered image");
- }
|