Files
rusty-rays/src/main.rs
2023-06-15 11:23:32 -04:00

144 lines
4.4 KiB
Rust

use std::f32;
mod camera;
use crate::camera::PerspectiveCamera;
mod renderer;
use crate::renderer::cast_ray;
//use crate::materials::{Material,SurfaceType};
mod elements;
use crate::elements::*;
#[macro_use]
extern crate bmp;
extern crate rand;
extern crate nalgebra;
use std::fs::File;
use std::path::*;
use rand::Rng;
use nalgebra::*;
use bmp::Image;
use bmp::Pixel;
use std::io::{Write,stdout};
use crossterm::{QueueableCommand,cursor,terminal,ExecutableCommand};
fn initialize_scene(camera: &mut PerspectiveCamera) {
camera.lights.push(LightSrc::new(Vec3::new(200.0, 800.0, 300.0), 5.0));
camera.lights.push(LightSrc::new(Vec3::new(1200.0, 800.0, 300.0), 5.0));
for i in 0..15 {
let mut rng = rand::thread_rng();
let x: f64 = rng.gen::<f64>() * 250.0 * 10.0;
let y: f64 = rng.gen::<f64>() * 250.0 * 10.0;
let z: f64 = rng.gen::<f64>() * 250.0 * 10.0;
let radius: f64 = rng.gen::<f64>() * 40.0 * 10.0;
let red: f32 = rng.gen::<f32>() * 100.0;
let green: f32 = rng.gen::<f32>() * 100.0;
let blue: f32 = rng.gen::<f32>() * 100.0;
let color = Color { red, green, blue };
let sphere = Sphere {
pos: Vec3::new(x, y, 100.0),
radius: radius,
material: Material::new(Coloration::Color(color), 2.0, SurfaceType::Reflective { reflectivity: rng.gen::<f32>() }),
};
//camera.elements.push(Element::Sphere(sphere));
}
let color = Color { red: 30.0, green: 30.0, blue: 30.0 };
let back_plane = Plane {
//pos: Vec3::new(0.0, 0.0, 100.0),
pos: Vec3::new(0.0, 0.0, 1500.0),
//color: Color::new(20.0, 20.0, 255.0),
material: Material::new(Coloration::Color(color), 2.0, SurfaceType::Diffuse),
normal: Vec3::new(0.0, 0.0, 1.0),
};
camera.elements.push(Element::Plane(back_plane));
// let bottom_plane = Plane {
// pos: Vec3::new(2500.0, 0.0, 1500.0),
// //color: Coloration::Texture(texture),
// //material: Material::new(Coloration::Texture(dummy_texture.clone()), 2.0, SurfaceType::Diffuse),
// normal: Vec3::new(0.0, 0.2, 1.0),
// };
//camera.elements.push(Element::Plane(bottom_plane));
let path = Path::new("texture/granite_base.png");
let texture_image = image::open(&path).unwrap();
let base_texture = Texture { texture: texture_image };
let center_sphere = Sphere {
pos: Vec3::new(1280.0, 1290.0, 1000.0),
radius: 300.0,
material: Material::new(Coloration::Texture(base_texture.clone()), 2.0, SurfaceType::Reflective { reflectivity: 0.1 }),
};
camera.elements.push(Element::Sphere(center_sphere));
let left_sphere = Sphere {
pos: Vec3::new(200.0, 1800.0, 500.0),
radius: 200.0,
material: Material::new(Coloration::Texture(base_texture.clone()), 2.0, SurfaceType::Reflective { reflectivity: 0.1 }),
};
camera.elements.push(Element::Sphere(left_sphere));
let top_sphere = Sphere {
pos: Vec3::new(1080.0, 700.0, 500.0),
radius: 200.0,
material: Material::new(Coloration::Texture(base_texture.clone()), 2.0, SurfaceType::Diffuse),
};
camera.elements.push(Element::Sphere(top_sphere));
}
fn main() {
let mut camera = PerspectiveCamera {
pos: Vec3::new(1280.0, 1280.0, -1000.0),
output_img: Image::new(2560,2560),
elements: Vec::new(),
lights: Vec::new(),
shadow_bias: 1e-3,
max_recursion_depth: 5,
fov: 90.0,
scene_width: 2560,
scene_height: 2560,
};
initialize_scene(&mut camera);
println!("Rusty Rays v1.0 Alpha\n");
println!("Raytracing...\n");
let mut stdout = stdout();
stdout.execute(cursor::Hide).unwrap();
stdout.write_all(format!("Progress: ").as_bytes()).unwrap();
for (x, y) in camera.output_img.coordinates() {
stdout.queue(cursor::SavePosition).unwrap();
stdout.write_all(format!("{:.1}%", camera.percent_complete(y)).as_bytes()).unwrap();
//stdout.write_all(format!("Raytracing.. {} : {}", x, y).as_bytes()).unwrap();
stdout.queue(cursor::RestorePosition).unwrap();
stdout.flush().unwrap();
//thread::sleep(time::Duration::from_millis(100));
stdout.queue(cursor::RestorePosition).unwrap();
stdout.queue(terminal::Clear(terminal::ClearType::FromCursorDown)).unwrap();
camera.output_img.set_pixel(x, y, px!(20, 20, 20));
let prime_ray = camera.create_prime(x, y);
let pixel = cast_ray(&camera, &prime_ray, 0);
camera.output_img.set_pixel(x, y, px!(pixel.red, pixel.green, pixel.blue));
}
stdout.queue(cursor::RestorePosition).unwrap();
println!("Render complete! 🎉");
let _ = camera.output_img.save("img.bmp");
}