triangle and fix cube normals

This commit is contained in:
STP
2023-11-28 17:10:21 -05:00
parent 144763d4d4
commit 055d14fb23
2 changed files with 48 additions and 38 deletions

View File

@@ -506,17 +506,17 @@ impl Primitive for Cube {
//Get normal of intersection point //Get normal of intersection point
let normal = if tmin == t1.x { let normal = if tmin == t1.x {
Vector3::new(-1.0, 0.0, 0.0) Vector3::new(1.0, 0.0, 0.0)
} else if tmin == t1.y { } else if tmin == t1.y {
Vector3::new(0.0, -1.0, 0.0) Vector3::new(0.0, -1.0, 0.0)
} else if tmin == t1.z { } else if tmin == t1.z {
Vector3::new(0.0, 0.0, -1.0) Vector3::new(0.0, 0.0, 1.0)
} else if tmin == t2.x { } else if tmin == t2.x {
Vector3::new(1.0, 0.0, 0.0) Vector3::new(-1.0, 0.0, 0.0)
} else if tmin == t2.y { } else if tmin == t2.y {
Vector3::new(0.0, 1.0, 0.0) Vector3::new(0.0, 1.0, 0.0)
} else { } else {
Vector3::new(0.0, 0.0, 1.0) Vector3::new(0.0, 0.0, -1.0)
}; };
Some(Intersection { Some(Intersection {
@@ -535,6 +535,8 @@ impl Primitive for Cube {
} }
// TRIANGLE ----------------------------------------------------------------- // TRIANGLE -----------------------------------------------------------------
// Points u,v,w will be pointing outward from uw x uv
// Using the right hand rule
#[derive(Clone)] #[derive(Clone)]
#[allow(dead_code)] #[allow(dead_code)]
pub struct Triangle { pub struct Triangle {
@@ -549,7 +551,7 @@ impl Triangle {
pub fn new(u: Point3<f64>, v: Point3<f64>, w: Point3<f64>) -> Rc<dyn Primitive> { pub fn new(u: Point3<f64>, v: Point3<f64>, w: Point3<f64>) -> Rc<dyn Primitive> {
let uv = v - u; let uv = v - u;
let uw = w - u; let uw = w - u;
let normal = uv.cross(&uw).normalize(); let normal = uw.cross(&uv).normalize();
let bln = u.inf(&v).inf(&w); let bln = u.inf(&v).inf(&w);
let trf = u.sup(&v).sup(&w); let trf = u.sup(&v).sup(&w);
let bounding_box = BoundingBox { bln, trf }; let bounding_box = BoundingBox { bln, trf };
@@ -572,40 +574,43 @@ impl Triangle {
impl Primitive for Triangle { impl Primitive for Triangle {
fn intersect_ray(&self, ray: &Ray) -> Option<Intersection> { fn intersect_ray(&self, ray: &Ray) -> Option<Intersection> {
let constant = self.u.coords.dot(&self.normal); let (u, v, w) = (self.u, self.v, self.w);
let denominator = ray.b.dot(&self.normal); let e1 = v - u;
let t = (constant - ray.a.coords.dot(&self.normal)) / denominator; let e2 = w - u;
let b_cross_e2 = ray.b.cross(&e2);
let det = e1.dot(&b_cross_e2);
if t > INFINITY { if det > -EPSILON && det < EPSILON {
return None; return None;
} }
let intersect = ray.at_t(t); let inv_det = 1.0 / det;
let s = ray.a - u;
let p = inv_det * s.dot(&b_cross_e2);
let uv = self.v - self.u; if p < 0.0 || p > 1.0 {
let vw = self.w - self.v; return None;
let wu = self.u - self.w;
let ui = intersect - self.u;
let vi = intersect - self.v;
let wi = intersect - self.w;
let u_cross = uv.cross(&ui);
let v_cross = vw.cross(&vi);
let w_cross = wu.cross(&wi);
let normal = self.normal;
if u_cross.dot(&normal) >= 0.0 && v_cross.dot(&normal) >= 0.0 && w_cross.dot(&normal) >= 0.0
{
Some(Intersection {
point: intersect,
normal: normal,
distance: t,
})
} else {
None
} }
let s_cross_e1 = s.cross(&e1);
let v = inv_det * ray.b.dot(&s_cross_e1);
if v < 0.0 || p + v > 1.0 {
return None;
}
let t = inv_det * e2.dot(&s_cross_e1);
if t > EPSILON
// ray intersection
{
let intersect = ray.at_t(t);
return Some(Intersection {
point: intersect,
normal: self.normal,
distance: t,
});
}
None
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn intersect_bounding_box(&self, ray: &Ray) -> bool {

View File

@@ -20,8 +20,8 @@ use winit::window::{Window, WindowBuilder};
const START_WIDTH: i32 = 1200; const START_WIDTH: i32 = 1200;
const START_HEIGHT: i32 = 700; const START_HEIGHT: i32 = 700;
const COLOUR_CLEAR: [u8; 4] = [0x22, 0x00, 0x11, 0xff]; const COLOUR_CLEAR: [u8; 4] = [0x22, 0x00, 0x11, 0x00];
const PIXEL_CLEAR: [u8; 4] = [0x55, 0x00, 0x22, 0xff]; const PIXEL_CLEAR: [u8; 4] = [0x55, 0x00, 0x22, 0x00];
pub const INIT_FILE: &str = "rhai/scene.rhai"; pub const INIT_FILE: &str = "rhai/scene.rhai";
pub const SAVE_FILE: &str = "img.png"; pub const SAVE_FILE: &str = "img.png";
@@ -153,9 +153,13 @@ impl State {
None => break, None => break,
}; };
//Shade colour for selected ray //Shade colour for selected ray
let colour = &self.rays[index].shade_ray(&self.scene); let rgba = match &self.rays[index].shade_ray(&self.scene, 0) {
//Assign colour to pixel in frame Some(mut colour) => {
let rgba = colour.map_or(PIXEL_CLEAR, |colour| [colour.x, colour.y, colour.z, 255]); colour = colour * 255.0;
[colour.x as u8, colour.y as u8, colour.z as u8, 0xff]
}
None => PIXEL_CLEAR,
};
frame[index * 4..(index + 1) * 4].copy_from_slice(&rgba); frame[index * 4..(index + 1) * 4].copy_from_slice(&rgba);
} }
Ok(()) Ok(())
@@ -248,6 +252,7 @@ fn create_window(event_loop: &EventLoop<()>) -> Window {
.with_title("Hello Pixels + Dear ImGui") .with_title("Hello Pixels + Dear ImGui")
.with_inner_size(size) .with_inner_size(size)
.with_min_inner_size(size) .with_min_inner_size(size)
.with_transparent(true)
.build(event_loop) .build(event_loop)
.unwrap() .unwrap()
} }