diff --git a/rhai/mesh.rhai b/rhai/mesh.rhai index b8c8313..d1a9ff9 100644 --- a/rhai/mesh.rhai +++ b/rhai/mesh.rhai @@ -10,11 +10,14 @@ scene.addCamera("Cam", camera); let falloff = V(0.0,0.0,0.0); let light = Light(P(6.0,6.0,6.0), V(0.4,0.4,0.4), falloff); +light.active(false); scene.addLight("white", light); -// let light = Light(P(2.0,0.0,0.0), V(0.0,1.0,0.0), V(0.1, 0.01, 0.001)); -// scene.addLight("green", light); -// let light = Light(P(-2.0,0.0,0.0), V(1.0,0.0,0.0), V(0.1, 0.01, 0.001)); -// scene.addLight("red", light); +let light = Light(P(2.0,0.0,0.0), V(0.0,1.0,0.0), V(0.1, 0.01, 0.001)); +light.active(false); +scene.addLight("green", light); +let light = Light(P(-2.0,0.0,0.0), V(1.0,0.0,0.0), V(0.1, 0.01, 0.001)); +light.active(false); +scene.addLight("red", light); let light = Ambient(V(0.3,0.3,0.3)); scene.addLight("ambient", light); @@ -31,9 +34,14 @@ scene.addNode("circle", circle_node); let cone = ConeUnit(); let cone_node = Node(cone, material); -cone_node.active(true); +cone_node.active(false); scene.addNode("cone", cone_node); +let torus = Torus(0.5, 1.5); +let torus_node = Node(torus, material); +torus_node.active(true); +scene.addNode("torus", torus_node); + let sphere = SphereUnit(); let sphere_node = Node(sphere, material); diff --git a/rhai/scene.rhai b/rhai/scene.rhai index 21ff694..c5d6516 100644 --- a/rhai/scene.rhai +++ b/rhai/scene.rhai @@ -17,13 +17,15 @@ scene.addCamera("-X Cam", camera); let material = Material(V(0.2,0.2,0.2), V(0.2, 0.8, 0.8), 10.0); scene.addMaterial("bluegreen", material); -// let light = Light(P(0.0,7.0,0.0), V(0.0,0.0,1.0), V(0.1, 0.01, 0.001)); -// scene.addLight("blue", light); +let light = Light(P(0.0,7.0,0.0), V(0.0,0.0,1.0), V(0.1, 0.01, 0.001)); +light.active(false); +scene.addLight("blue", light); -// let light = Light( P(2.0,7.0,0.0), V(0.0,1.0,0.0), V(0.1, 0.01, 0.001)); -// scene.addLight("green", light); +let light = Light( P(2.0,7.0,0.0), V(0.0,1.0,0.0), V(0.1, 0.01, 0.001)); +light.active(false); +scene.addLight("green", light); -let light = Light( P(-2.0,7.0,0.0), V(1.0,0.0,0.0), V(0.1, 0.01, 0.001)); +let light = Light( P(2.0,7.0,2.0), V(1.0,0.0,0.0), V(0.1, 0.01, 0.001)); scene.addLight("red", light); let light = Ambient(V(0.1,0.1,0.1)); @@ -41,7 +43,7 @@ let sphere_node = Node(sphere, material); for i in 0..6 { let sphere = Sphere(P(0.0,0.0,0.0), 2.0 ); let sphere_node = Node(sphere, material); - sphere_node.translate(2.0*cos(i.to_float()), -4.0, 2.0*sin(i.to_float())); + sphere_node.translate(4.0*cos(i.to_float()), -4.0, 4.0*sin(i.to_float())); scene.addNode(i.to_string(), sphere_node); } // let child = sphere_node.child(sphere); diff --git a/src/primitive.rs b/src/primitive.rs index 2781c6e..a11a04c 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -6,7 +6,7 @@ use crate::{ #[allow(dead_code)] use nalgebra::{distance, Point3, Vector3}; -use roots::{find_roots_quadratic, find_roots_quartic, FloatType, Roots}; +use roots::{find_roots_quadratic, find_roots_quartic, Roots}; use std::fs::File; use std::io::{BufRead, BufReader}; use std::rc::Rc; @@ -44,7 +44,7 @@ impl Sphere { impl Primitive for Sphere { fn intersect_ray(&self, ray: &Ray) -> Option { - let pos = &ray.a; + let pos = ray.a; let dir = &ray.b; let l = pos - self.position; diff --git a/src/state.rs b/src/state.rs index 3076e97..653025a 100644 --- a/src/state.rs +++ b/src/state.rs @@ -6,8 +6,9 @@ use crate::{gui::Gui, scene::Scene}; use crate::{gui::GuiEvent, log_error}; use std::path::Path; +use nalgebra::Vector3; use rand::seq::SliceRandom; -use rand::thread_rng; +use rand::{random, thread_rng}; use std::error::Error; @@ -20,8 +21,10 @@ use winit::window::{Window, WindowBuilder}; const START_WIDTH: i32 = 1200; const START_HEIGHT: i32 = 700; -const COLOUR_CLEAR: [u8; 4] = [0x22, 0x00, 0x11, 0x00]; -const PIXEL_CLEAR: [u8; 4] = [0x55, 0x00, 0x22, 0x00]; +const RAY_SAMPLES: i8 = 5; +const RAY_RANDOMNESS: f64 = 100.0; +const COLOUR_CLEAR: [u8; 4] = [0x22, 0x00, 0x11, 0x55]; +const PIXEL_CLEAR: [u8; 4] = [0x55, 0x00, 0x22, 0x55]; pub const INIT_FILE: &str = "rhai/scene.rhai"; pub const SAVE_FILE: &str = "img.png"; @@ -153,13 +156,26 @@ impl State { None => break, }; //Shade colour for selected ray - let rgba = match &self.rays[index].shade_ray(&self.scene, 0) { - Some(mut colour) => { - colour = colour * 255.0; - [colour.x as u8, colour.y as u8, colour.z as u8, 0xff] - } - None => PIXEL_CLEAR, - }; + let mut colour = Vector3::zeros(); + for _ in 0..RAY_SAMPLES { + let ray = &self.rays[index]; + let point = ray.a; + let dir = ray.b; + let rx = (random::() - 0.5) / RAY_RANDOMNESS; + let ry = (random::() - 0.5) / RAY_RANDOMNESS; + let rz = (random::() - 0.5) / RAY_RANDOMNESS; + let nx = dir.x + rx; + let ny = dir.y + ry; + let nz = dir.z + rz; + + let rand_ray = Ray::new(point, Vector3::new(nx, ny, nz)); + + if let Some(ray_colour) = rand_ray.shade_ray(&self.scene, 0) { + colour += ray_colour; + }; + } + colour = (colour / RAY_SAMPLES as f32) * 255.0; + let rgba = [colour.x as u8, colour.y as u8, colour.z as u8, 0xff]; frame[index * 4..(index + 1) * 4].copy_from_slice(&rgba); } Ok(())