128 lines
4.1 KiB
Rust
128 lines
4.1 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(1800.0, 900.0, 300.0), 2.0));
|
|
camera.lights.push(LightSrc::new(Vec3::new(1100.0, 800.0, 300.0), 2.0));
|
|
|
|
|
|
//let color = Color { red: 30.0, green: 30.0, blue: 30.0 };
|
|
let back_texture_path = Path::new("texture/tiles_base.png");
|
|
let back_height_path = Path::new("texture/tiles_height.png");
|
|
|
|
let back_texture_image = image::open(&back_texture_path).unwrap();
|
|
let back_height_image = image::open(&back_height_path).unwrap();
|
|
|
|
let back_texture = Texture { texture: back_texture_image.clone(), heightmap: back_height_image.clone() };
|
|
|
|
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::Texture(back_texture), 2.0, SurfaceType::Diffuse),
|
|
normal: Vec3::new(0.0, 0.0, 1.0),
|
|
};
|
|
camera.elements.push(Element::Plane(back_plane));
|
|
|
|
let texture_path = Path::new("texture/granite_base.png");
|
|
let height_path = Path::new("texture/granite_height.png");
|
|
let normal_path = Path::new("texture/granite_normal.png");
|
|
|
|
let texture_image = image::open(&texture_path).unwrap();
|
|
let height_image = image::open(&height_path).unwrap();
|
|
let normal_image = image::open(&normal_path).unwrap();
|
|
|
|
let base_texture = Texture { texture: texture_image.clone(), heightmap: height_image };
|
|
|
|
let left_sphere = Sphere {
|
|
pos: Vec3::new(800.0, 1290.0, 1000.0),
|
|
radius: 300.0,
|
|
material: Material::new(Coloration::Texture(base_texture.clone()), 2.0, SurfaceType::Diffuse),
|
|
};
|
|
camera.elements.push(Element::Sphere(left_sphere));
|
|
|
|
let right_sphere = Sphere {
|
|
pos: Vec3::new(1480.0, 1290.0, 1000.0),
|
|
radius: 300.0,
|
|
material: Material::new(Coloration::Texture(base_texture.clone()), 2.0, SurfaceType::Diffuse),
|
|
};
|
|
camera.elements.push(Element::Sphere(right_sphere));
|
|
|
|
let sphere_color = Color { red: 60.0, green: 60.0, blue: 60.0 };
|
|
let center_sphere = Sphere {
|
|
pos: Vec3::new(1280.0, 690.0, 1100.0),
|
|
radius: 300.0,
|
|
material: Material::new(Coloration::Color(sphere_color), 2.0, SurfaceType::Reflective { reflectivity: 0.2 }),
|
|
};
|
|
camera.elements.push(Element::Sphere(center_sphere));
|
|
}
|
|
|
|
fn main() {
|
|
let mut camera = PerspectiveCamera {
|
|
pos: Vec3::new(1280.0, 1280.0, -200.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");
|
|
}
|