More gui options!
This commit is contained in:
@@ -277,6 +277,10 @@ impl Gui {
|
|||||||
);
|
);
|
||||||
// Enable BVH
|
// Enable BVH
|
||||||
ui.checkbox("Enable BVH", &mut self.raytracing_option.bvh_active);
|
ui.checkbox("Enable BVH", &mut self.raytracing_option.bvh_active);
|
||||||
|
ui.checkbox("Enable Shadows", &mut self.raytracing_option.shadows);
|
||||||
|
ui.checkbox("Enable Reflections", &mut self.raytracing_option.reflect);
|
||||||
|
ui.checkbox("Enable Specular", &mut self.raytracing_option.specular);
|
||||||
|
ui.checkbox("Enable Diffuse", &mut self.raytracing_option.diffuse);
|
||||||
// Apply stored changes
|
// Apply stored changes
|
||||||
if ui.button("Apply") {
|
if ui.button("Apply") {
|
||||||
self.event = Some(GuiEvent::RaytracerOption(self.raytracing_option.clone()));
|
self.event = Some(GuiEvent::RaytracerOption(self.raytracing_option.clone()));
|
||||||
@@ -346,9 +350,7 @@ impl Gui {
|
|||||||
// SCENE --------------------------------------------
|
// SCENE --------------------------------------------
|
||||||
if CollapsingHeader::new("Scene").build(ui) {
|
if CollapsingHeader::new("Scene").build(ui) {
|
||||||
if ui.button("Update Scene") {
|
if ui.button("Update Scene") {
|
||||||
for (_, node) in &mut self.scene.nodes {
|
self.scene.compute();
|
||||||
node.compute();
|
|
||||||
}
|
|
||||||
self.event = Some(GuiEvent::SceneLoad(self.scene.clone()));
|
self.event = Some(GuiEvent::SceneLoad(self.scene.clone()));
|
||||||
}
|
}
|
||||||
// Edit transformation of nodes
|
// Edit transformation of nodes
|
||||||
|
|||||||
271
src/main.rs
271
src/main.rs
@@ -1,23 +1,12 @@
|
|||||||
use crate::state::run;
|
use crate::state::run;
|
||||||
use bvh::BVH;
|
|
||||||
use camera::Camera;
|
|
||||||
use error_iter::ErrorIter;
|
use error_iter::ErrorIter;
|
||||||
|
|
||||||
const EPSILON: f64 = 1e-8;
|
const EPSILON: f64 = 1e-8;
|
||||||
const INFINITY: f64 = 1e10;
|
const INFINITY: f64 = 1e10;
|
||||||
|
|
||||||
use gui::{init_engine};
|
|
||||||
use log::error;
|
use log::error;
|
||||||
use nalgebra::Vector3;
|
|
||||||
use rand::random;
|
|
||||||
use ray::Ray;
|
|
||||||
use scene::Scene;
|
|
||||||
use state::RaytracingOption;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::Mutex;
|
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
mod bvh;
|
mod bvh;
|
||||||
mod camera;
|
mod camera;
|
||||||
@@ -33,143 +22,143 @@ mod state;
|
|||||||
fn main() {
|
fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
env::set_var("RUST_BACKTRACE", "1");
|
env::set_var("RUST_BACKTRACE", "1");
|
||||||
let args: Vec<String> = env::args().collect();
|
//let args: Vec<String> = env::args().collect();
|
||||||
|
|
||||||
if args.len() == 6 {
|
|
||||||
let width: usize = args[1].parse().unwrap();
|
|
||||||
let height: usize = args[2].parse().unwrap();
|
|
||||||
let fovy = args[3].parse::<f64>().unwrap();
|
|
||||||
let filename = &args[4];
|
|
||||||
let savefile = &args[5];
|
|
||||||
headless(
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
fovy,
|
|
||||||
filename.to_string(),
|
|
||||||
savefile.to_string(),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if let Err(e) = run() {
|
if let Err(e) = run() {
|
||||||
println!("Error at runtime: {}", e);
|
println!("Error at runtime: {}", e);
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
// if args.len() == 6 {
|
||||||
|
// let width: usize = args[1].parse().unwrap();
|
||||||
|
// let height: usize = args[2].parse().unwrap();
|
||||||
|
// let fovy = args[3].parse::<f64>().unwrap();
|
||||||
|
// let filename = &args[4];
|
||||||
|
// let savefile = &args[5];
|
||||||
|
// headless(
|
||||||
|
// width,
|
||||||
|
// height,
|
||||||
|
// fovy,
|
||||||
|
// filename.to_string(),
|
||||||
|
// savefile.to_string(),
|
||||||
|
// );
|
||||||
|
// } else {
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn headless(width: usize, height: usize, fovy: f64, filename: String, savefile: String) {
|
// fn headless(width: usize, height: usize, fovy: f64, filename: String, savefile: String) {
|
||||||
let options = Arc::new(RaytracingOption {
|
// let options = Arc::new(RaytracingOption {
|
||||||
threads: 12,
|
// threads: 12,
|
||||||
ray_samples: 1,
|
// ray_samples: 1,
|
||||||
ray_randomness: 100.0,
|
// ray_randomness: 100.0,
|
||||||
clear_color: [0x22, 0x00, 0x11, 0x55],
|
// clear_color: [0x22, 0x00, 0x11, 0x55],
|
||||||
pixel_clear: [0x55, 0x00, 0x22, 0x55],
|
// pixel_clear: [0x55, 0x00, 0x22, 0x55],
|
||||||
pixels_per_thread: 200,
|
// pixels_per_thread: 200,
|
||||||
buffer_proportion: 1.0,
|
// buffer_proportion: 1.0,
|
||||||
buffer_fov: 110.0,
|
// buffer_fov: 110.0,
|
||||||
ray_depth: 5,
|
// ray_depth: 5,
|
||||||
diffuse_rays: 3,
|
// diffuse_rays: 3,
|
||||||
diffuse_coefficient: 0.8,
|
// diffuse_coefficient: 0.8,
|
||||||
bvh_active: false,
|
// bvh_active: false,
|
||||||
});
|
// });
|
||||||
//Read script from file
|
// //Read script from file
|
||||||
let script = match std::fs::read_to_string(&filename) {
|
// let script = match std::fs::read_to_string(&filename) {
|
||||||
Ok(in_script) => in_script,
|
// Ok(in_script) => in_script,
|
||||||
Err(e) => {
|
// Err(e) => {
|
||||||
println!("{}", e);
|
// println!("{}", e);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
//Evaluate scene in file
|
// //Evaluate scene in file
|
||||||
let engine = init_engine();
|
// let engine = init_engine();
|
||||||
let scene: Arc<Scene> = match engine.eval(&script) {
|
// let scene: Arc<Scene> = match engine.eval(&script) {
|
||||||
Ok(in_scene) => Arc::new(in_scene),
|
// Ok(in_scene) => Arc::new(in_scene),
|
||||||
Err(e) => {
|
// Err(e) => {
|
||||||
println!("{e}");
|
// println!("{e}");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
//Set the camera
|
// //Set the camera
|
||||||
let mut camera = Camera::unit();
|
// let mut camera = Camera::unit();
|
||||||
for (_, in_camera) in &scene.cameras {
|
// for (_, in_camera) in &scene.cameras {
|
||||||
camera = in_camera.clone();
|
// camera = in_camera.clone();
|
||||||
}
|
// }
|
||||||
//Cast the rays
|
// //Cast the rays
|
||||||
let rays = Arc::new(Ray::cast_rays(
|
// let rays = Arc::new(Ray::cast_rays(
|
||||||
&camera.eye,
|
// &camera.eye,
|
||||||
&camera.target,
|
// &camera.target,
|
||||||
&camera.up,
|
// &camera.up,
|
||||||
fovy,
|
// fovy,
|
||||||
width as u32,
|
// width as u32,
|
||||||
height as u32,
|
// height as u32,
|
||||||
));
|
// ));
|
||||||
//Enable bounding volume heirarchy
|
// //Enable bounding volume heirarchy
|
||||||
let bvh;
|
// let bvh;
|
||||||
match options.bvh_active {
|
// match options.bvh_active {
|
||||||
true => bvh = Arc::new(Some(BVH::build(&scene.nodes))),
|
// true => bvh = Arc::new(Some(BVH::build(&scene.nodes))),
|
||||||
false => bvh = Arc::new(None),
|
// false => bvh = Arc::new(None),
|
||||||
}
|
// }
|
||||||
//Create our frame and indexer
|
// //Create our frame and indexer
|
||||||
let size = width * height;
|
// let size = width * height;
|
||||||
let frame_mutex = Arc::new(Mutex::new(vec![0; size * 4]));
|
// let frame_mutex = Arc::new(Mutex::new(vec![0; size * 4]));
|
||||||
//Multithreading
|
// //Multithreading
|
||||||
let mut handles = vec![];
|
// let mut handles = vec![];
|
||||||
|
|
||||||
for index in 0..size {
|
// for index in 0..size {
|
||||||
for _ in 0..options.threads {
|
// for _ in 0..options.threads {
|
||||||
//Get random index from queue
|
// //Get random index from queue
|
||||||
//Create a nre thread for this pixel
|
// //Create a nre thread for this pixel
|
||||||
let handle = thread::spawn({
|
// let handle = thread::spawn({
|
||||||
let rays = rays.clone();
|
// let rays = rays.clone();
|
||||||
let scene = scene.clone();
|
// let scene = scene.clone();
|
||||||
let options = options.clone();
|
// let options = options.clone();
|
||||||
let bvh = bvh.clone();
|
// let bvh = bvh.clone();
|
||||||
let rays = rays.clone();
|
// let rays = rays.clone();
|
||||||
let frame_mutex = frame_mutex.clone();
|
// let frame_mutex = frame_mutex.clone();
|
||||||
move || {
|
// move || {
|
||||||
//Shade colour for selected ray
|
// //Shade colour for selected ray
|
||||||
let mut colour: Vector3<f32> = Vector3::zeros();
|
// let mut colour: Vector3<f32> = Vector3::zeros();
|
||||||
//Get the ray we want to make
|
// //Get the ray we want to make
|
||||||
let shot_ray = &rays[index];
|
// let shot_ray = &rays[index];
|
||||||
//Send out ray_samples rays
|
// //Send out ray_samples rays
|
||||||
for _ in 0..options.ray_samples {
|
// for _ in 0..options.ray_samples {
|
||||||
let point = shot_ray.a;
|
// let point = shot_ray.a;
|
||||||
let dir = shot_ray.b;
|
// let dir = shot_ray.b;
|
||||||
//Generate a random ray
|
// //Generate a random ray
|
||||||
let rx = (random::<f64>() - 0.5) / options.ray_randomness;
|
// let rx = (random::<f64>() - 0.5) / options.ray_randomness;
|
||||||
let ry = (random::<f64>() - 0.5) / options.ray_randomness;
|
// let ry = (random::<f64>() - 0.5) / options.ray_randomness;
|
||||||
let rz = (random::<f64>() - 0.5) / options.ray_randomness;
|
// let rz = (random::<f64>() - 0.5) / options.ray_randomness;
|
||||||
let nx = dir.x + rx;
|
// let nx = dir.x + rx;
|
||||||
let ny = dir.y + ry;
|
// let ny = dir.y + ry;
|
||||||
let nz = dir.z + rz;
|
// let nz = dir.z + rz;
|
||||||
let rand_ray = Ray::new(point, Vector3::new(nx, ny, nz));
|
// let rand_ray = Ray::new(point, Vector3::new(nx, ny, nz));
|
||||||
|
|
||||||
if let Some(ray_colour) = rand_ray.shade_ray(&scene, 0, &options, &bvh) {
|
// if let Some(ray_colour) = rand_ray.shade_ray(&scene, 0, &options, &bvh) {
|
||||||
colour += ray_colour;
|
// colour += ray_colour;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
colour = (colour / options.ray_samples as f32) * 255.0;
|
// colour = (colour / options.ray_samples as f32) * 255.0;
|
||||||
let rgba = [colour.x as u8, colour.y as u8, colour.z as u8, 0xff];
|
// let rgba = [colour.x as u8, colour.y as u8, colour.z as u8, 0xff];
|
||||||
{
|
// {
|
||||||
let frame = &mut frame_mutex.lock().unwrap();
|
// let frame = &mut frame_mutex.lock().unwrap();
|
||||||
frame[index * 4..(index + 1) * 4].copy_from_slice(&rgba);
|
// frame[index * 4..(index + 1) * 4].copy_from_slice(&rgba);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
handles.push(handle);
|
// handles.push(handle);
|
||||||
}
|
// }
|
||||||
for handle in handles.drain(..) {
|
// for handle in handles.drain(..) {
|
||||||
handle.join().unwrap();
|
// handle.join().unwrap();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
use std::path::Path;
|
// use std::path::Path;
|
||||||
image::save_buffer(
|
// image::save_buffer(
|
||||||
Path::new(&savefile),
|
// Path::new(&savefile),
|
||||||
&frame_mutex.lock().unwrap(),
|
// &frame_mutex.lock().unwrap(),
|
||||||
width as u32,
|
// width as u32,
|
||||||
height as u32,
|
// height as u32,
|
||||||
image::ColorType::Rgba8,
|
// image::ColorType::Rgba8,
|
||||||
)
|
// )
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn log_error<E: Error + 'static>(method_name: &str, err: E) {
|
fn log_error<E: Error + 'static>(method_name: &str, err: E) {
|
||||||
error!("{method_name}() failed: {err}");
|
error!("{method_name}() failed: {err}");
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
bvh::AABB,
|
bvh::AABB,
|
||||||
material::Material,
|
material::Material,
|
||||||
primitive::{*},
|
primitive::*,
|
||||||
ray::{Intersection, Ray},
|
ray::{Intersection, Ray},
|
||||||
|
EPSILON,
|
||||||
};
|
};
|
||||||
use nalgebra::{Matrix4, Vector3};
|
use nalgebra::{Matrix4, Vector3};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -107,6 +108,9 @@ impl Node {
|
|||||||
pub fn intersect_ray(&self, ray: &Ray) -> Option<Intersection> {
|
pub fn intersect_ray(&self, ray: &Ray) -> Option<Intersection> {
|
||||||
let ray = ray.transform(&self.inv_model); //Transform from world coordinates
|
let ray = ray.transform(&self.inv_model); //Transform from world coordinates
|
||||||
if let Some(mut intersect) = self.primitive.intersect_ray(&ray) {
|
if let Some(mut intersect) = self.primitive.intersect_ray(&ray) {
|
||||||
|
if intersect.distance < EPSILON {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
intersect.transform_mut(&self.model, &self.inv_model); //Transform to world coords
|
intersect.transform_mut(&self.model, &self.inv_model); //Transform to world coords
|
||||||
return Some(intersect);
|
return Some(intersect);
|
||||||
}
|
}
|
||||||
|
|||||||
39
src/ray.rs
39
src/ray.rs
@@ -70,8 +70,7 @@ impl Ray {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Transform ray into local model cordinates
|
// Transform ray into local model cordinates
|
||||||
let ray = ray.transform(&node.inv_model);
|
if node.intersect_ray(&ray).is_some() {
|
||||||
if node.primitive.intersect_ray(&ray).is_some() {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,16 +92,13 @@ impl Ray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if node.aabb.intersect_ray(&ray) {
|
if node.aabb.intersect_ray(&ray) {
|
||||||
// Transform ray into model cordinates
|
//Check node intersection
|
||||||
let ray = ray.transform(&node.inv_model);
|
if let Some(intersect) = node.intersect_ray(&ray) {
|
||||||
// Check primitive intersection
|
|
||||||
if let Some(mut intersect) = node.primitive.intersect_ray(&ray) {
|
|
||||||
// Dont intersect with own primitive
|
// Dont intersect with own primitive
|
||||||
if intersect.distance < EPSILON {
|
if intersect.distance < EPSILON {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Check for closest distance by converting to world coords
|
// Check for closest distance by converting to world coords
|
||||||
intersect.transform_mut(&node.model, &node.inv_model);
|
|
||||||
let distance = distance(&ray_a, &intersect.point);
|
let distance = distance(&ray_a, &intersect.point);
|
||||||
if distance < closest_distance {
|
if distance < closest_distance {
|
||||||
closest_distance = distance;
|
closest_distance = distance;
|
||||||
@@ -162,9 +158,8 @@ impl Ray {
|
|||||||
bvh: &Option<BVH>,
|
bvh: &Option<BVH>,
|
||||||
) -> Vector3<f32> {
|
) -> Vector3<f32> {
|
||||||
let normal = &intersect.normal;
|
let normal = &intersect.normal;
|
||||||
let point = intersect.point + normal * 0.0001;
|
let point = &intersect.point;
|
||||||
let incidence = &ray.b;
|
let incidence = &ray.b;
|
||||||
|
|
||||||
let material = &node.material;
|
let material = &node.material;
|
||||||
|
|
||||||
// Compute the ambient light component and set it as base colour
|
// Compute the ambient light component and set it as base colour
|
||||||
@@ -185,23 +180,28 @@ impl Ray {
|
|||||||
let to_light = to_light.normalize();
|
let to_light = to_light.normalize();
|
||||||
|
|
||||||
//Niave Shadows
|
//Niave Shadows
|
||||||
// let to_light_ray = Ray::new(point, to_light);
|
if options.shadows {
|
||||||
// if to_light_ray.light_blocked(scene, node, bvh) {
|
let to_light_ray = Ray::new(*point, to_light);
|
||||||
// continue;
|
if to_light_ray.light_blocked(scene, node, bvh) {
|
||||||
// }
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let n_dot_l = normal.dot(&to_light).max(0.0) as f32;
|
let n_dot_l = normal.dot(&to_light).max(0.0) as f32;
|
||||||
|
|
||||||
//Reflected component
|
//Reflected component
|
||||||
let mut reflect = Vector3::zeros();
|
let mut reflect = Vector3::zeros();
|
||||||
|
if options.reflect {
|
||||||
let reflect_dir = incidence - 2.0 * incidence.dot(&normal) * normal;
|
let reflect_dir = incidence - 2.0 * incidence.dot(&normal) * normal;
|
||||||
let reflect_ray = Ray::new(point, reflect_dir);
|
let reflect_ray = Ray::new(*point, reflect_dir);
|
||||||
if let Some(col) = reflect_ray.shade_ray(scene, depth + 1, options, bvh) {
|
if let Some(col) = reflect_ray.shade_ray(scene, depth + 1, options, bvh) {
|
||||||
reflect += col.component_mul(&material.kr)
|
reflect += col.component_mul(&material.kr)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Diffuse component (Lambertian)
|
//Diffuse component (Lambertian)
|
||||||
let mut diffuse = Vector3::zeros();
|
let mut diffuse = Vector3::zeros();
|
||||||
|
if options.diffuse {
|
||||||
diffuse += material.kd * n_dot_l;
|
diffuse += material.kd * n_dot_l;
|
||||||
for _ in 0..options.diffuse_rays {
|
for _ in 0..options.diffuse_rays {
|
||||||
let diffuse_dir = random_unit_vec();
|
let diffuse_dir = random_unit_vec();
|
||||||
@@ -210,20 +210,26 @@ impl Ray {
|
|||||||
diffuse += col * options.diffuse_coefficient;
|
diffuse += col * options.diffuse_coefficient;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Specular component
|
//Specular component
|
||||||
let mut specular = Vector3::zeros();
|
let mut specular = Vector3::zeros();
|
||||||
|
if options.specular {
|
||||||
if n_dot_l > 0.0 {
|
if n_dot_l > 0.0 {
|
||||||
let h = (to_light - incidence).normalize();
|
let h = (to_light - incidence).normalize();
|
||||||
let n_dot_h = normal.dot(&h).max(0.0) as f32;
|
let n_dot_h = normal.dot(&h).max(0.0) as f32;
|
||||||
specular = material.ks * n_dot_h.powf(material.shininess);
|
specular = material.ks * n_dot_h.powf(material.shininess);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Falloff
|
//Falloff
|
||||||
let falloff = 1.0
|
let mut falloff = 1.0;
|
||||||
|
if options.falloff {
|
||||||
|
falloff = 1.0
|
||||||
/ ((1.0 + light.falloff[0])
|
/ ((1.0 + light.falloff[0])
|
||||||
+ light.falloff[1] * light_distance
|
+ light.falloff[1] * light_distance
|
||||||
+ light.falloff[2] * light_distance * light_distance);
|
+ light.falloff[2] * light_distance * light_distance);
|
||||||
|
}
|
||||||
|
|
||||||
let intensity = light.colour.component_mul(&(diffuse + reflect + specular)) * falloff;
|
let intensity = light.colour.component_mul(&(diffuse + reflect + specular)) * falloff;
|
||||||
colour += &intensity;
|
colour += &intensity;
|
||||||
@@ -253,8 +259,7 @@ impl Ray {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if node.aabb.intersect_ray(self) {
|
if node.aabb.intersect_ray(self) {
|
||||||
let ray = self.transform(&node.inv_model);
|
if node.intersect_ray(self).is_some() {
|
||||||
if node.primitive.intersect_ray(&ray).is_some() {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/scene.rs
24
src/scene.rs
@@ -1,24 +1,6 @@
|
|||||||
use crate::{camera::Camera, light::Light, material::*, node::*};
|
use crate::{camera::Camera, light::Light, material::*, node::*};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
|
||||||
// pub struct MultiThreadScene {
|
|
||||||
// pub nodes: Rc<HashMap<String, Node>>,
|
|
||||||
// pub materials: Rc<HashMap<String, Material>>,
|
|
||||||
// pub lights: Rc<HashMap<String, Light>>,
|
|
||||||
// pub cameras: Rc<HashMap<String, Camera>>,
|
|
||||||
// }
|
|
||||||
// impl MultiThreadScene {
|
|
||||||
// pub fn from_scene(scene: &Scene) -> MultiThreadScene {
|
|
||||||
// MultiThreadScene {
|
|
||||||
// nodes: Rc::new(scene.nodes.clone()),
|
|
||||||
// materials: Rc::new(scene.materials.clone()),
|
|
||||||
// lights: Rc::new(scene.lights.clone()),
|
|
||||||
// cameras: Rc::new(scene.cameras.clone()),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
pub nodes: HashMap<String, Node>,
|
pub nodes: HashMap<String, Node>,
|
||||||
@@ -53,4 +35,10 @@ impl Scene {
|
|||||||
pub fn add_camera(&mut self, label: String, camera: Camera) {
|
pub fn add_camera(&mut self, label: String, camera: Camera) {
|
||||||
self.cameras.insert(label, camera);
|
self.cameras.insert(label, camera);
|
||||||
}
|
}
|
||||||
|
// Compute all matricies for nodes
|
||||||
|
pub fn compute(&mut self) {
|
||||||
|
for (_, node) in &mut self.nodes {
|
||||||
|
node.compute();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/state.rs
11
src/state.rs
@@ -42,6 +42,11 @@ pub struct RaytracingOption {
|
|||||||
pub diffuse_rays: u8,
|
pub diffuse_rays: u8,
|
||||||
pub diffuse_coefficient: f32,
|
pub diffuse_coefficient: f32,
|
||||||
pub bvh_active: bool,
|
pub bvh_active: bool,
|
||||||
|
pub shadows: bool,
|
||||||
|
pub diffuse: bool,
|
||||||
|
pub reflect: bool,
|
||||||
|
pub specular: bool,
|
||||||
|
pub falloff: bool,
|
||||||
}
|
}
|
||||||
impl RaytracingOption {
|
impl RaytracingOption {
|
||||||
pub fn default() -> RaytracingOption {
|
pub fn default() -> RaytracingOption {
|
||||||
@@ -58,6 +63,11 @@ impl RaytracingOption {
|
|||||||
diffuse_rays: 3,
|
diffuse_rays: 3,
|
||||||
diffuse_coefficient: 0.8,
|
diffuse_coefficient: 0.8,
|
||||||
bvh_active: false,
|
bvh_active: false,
|
||||||
|
shadows: true,
|
||||||
|
diffuse: true,
|
||||||
|
reflect: true,
|
||||||
|
specular: true,
|
||||||
|
falloff: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,6 +238,7 @@ impl State {
|
|||||||
let mut colour: Vector3<f32> = Vector3::zeros();
|
let mut colour: Vector3<f32> = Vector3::zeros();
|
||||||
let ray = &rays[*index];
|
let ray = &rays[*index];
|
||||||
for _ in 0..samples {
|
for _ in 0..samples {
|
||||||
|
//Generate a ray in a random direction
|
||||||
let point = ray.a;
|
let point = ray.a;
|
||||||
let dir = ray.b;
|
let dir = ray.b;
|
||||||
let rx = (random::<f64>() - 0.5) / randomness;
|
let rx = (random::<f64>() - 0.5) / randomness;
|
||||||
|
|||||||
Reference in New Issue
Block a user