Move Material to new module && TriangleBVH intersect && Seperate light and material
This commit is contained in:
parent
50d3874467
commit
b3fdef8837
18 changed files with 180 additions and 90 deletions
|
|
@ -6,3 +6,4 @@ edition = "2021"
|
|||
[dependencies]
|
||||
rand = "0.8.5"
|
||||
ray-tracing-core = { path = "../ray-tracing-core" }
|
||||
ray-tracing-material = { path = "../ray-tracing-material" }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use rand::Rng;
|
||||
use ray_tracing_core::material::DefaultMaterial;
|
||||
use ray_tracing_core::prelude::*;
|
||||
use ray_tracing_core::scene::{Intersection, Scene};
|
||||
use ray_tracing_material::default::DefaultMaterial;
|
||||
|
||||
pub struct BasicScene {
|
||||
pub(crate) spheres: Vec<(Pos3, Float)>,
|
||||
|
|
@ -30,7 +30,8 @@ impl<R: Rng> Scene<R> for BasicScene {
|
|||
let int = Intersection::new(
|
||||
d,
|
||||
((ray.start() + d * ray.dir()) - c).normalize(),
|
||||
&DefaultMaterial {},
|
||||
Some(&DefaultMaterial {}),
|
||||
None,
|
||||
);
|
||||
if d >= min && d <= max {
|
||||
if let Some(i) = intersection.as_ref() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,2 @@
|
|||
use rand::Rng;
|
||||
use ray_tracing_core::material::DefaultMaterial;
|
||||
use ray_tracing_core::prelude::*;
|
||||
|
||||
pub mod basic_scene;
|
||||
|
||||
pub mod triangle_bvh;
|
||||
|
|
|
|||
|
|
@ -9,10 +9,15 @@ type Index = u32;
|
|||
pub struct TriangleBVH<R: Rng> {
|
||||
vertices: Vec<Pos3>,
|
||||
triangles: Vec<Triangle>,
|
||||
materials: Vec<Box<dyn Material<R>>>,
|
||||
materials: Vec<BVHMaterial<R>>,
|
||||
bvh: Vec<Node>,
|
||||
}
|
||||
|
||||
struct BVHMaterial<R: Rng> {
|
||||
material: Option<Box<dyn Material<R>>>,
|
||||
light: Option<Box<dyn Light<R>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Node {
|
||||
Inner {
|
||||
|
|
@ -53,7 +58,7 @@ fn triangle_intersection(ray: Ray, v: [Pos3; 3]) -> Option<Float> {
|
|||
let inv_det = 1.0 / det;
|
||||
let s = ray.start() - v[0];
|
||||
let u = inv_det * s.dot(ray_cross_e2);
|
||||
if u < 0.0 || u > 1.0 {
|
||||
if !(0.0..=1.0).contains(&u) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
@ -82,11 +87,7 @@ fn triangle_normal(v: [Pos3; 3]) -> Dir3 {
|
|||
}
|
||||
|
||||
impl<R: Rng> TriangleBVH<R> {
|
||||
fn new(
|
||||
vertices: Vec<Pos3>,
|
||||
triangles: Vec<Triangle>,
|
||||
materials: Vec<Box<dyn Material<R>>>,
|
||||
) -> Self {
|
||||
fn new(vertices: Vec<Pos3>, triangles: Vec<Triangle>, materials: Vec<BVHMaterial<R>>) -> Self {
|
||||
Self {
|
||||
vertices,
|
||||
bvh: vec![Node::Leaf {
|
||||
|
|
@ -120,7 +121,40 @@ impl<R: Rng> TriangleBVH<R> {
|
|||
left_aabb,
|
||||
right,
|
||||
right_aabb,
|
||||
} => todo!(),
|
||||
} => {
|
||||
let left_intersect = left_aabb.intersect_ray(ray, min, max);
|
||||
let right_intersect = right_aabb.intersect_ray(ray, min, max);
|
||||
|
||||
match (left_intersect, right_intersect) {
|
||||
(None, None) => None,
|
||||
(None, Some(_)) => self.intersect_bvh(right, ray, min, max),
|
||||
(Some(_), None) => self.intersect_bvh(left, ray, min, max),
|
||||
(Some(l), Some(r)) => {
|
||||
let close;
|
||||
let far;
|
||||
if l < r {
|
||||
close = left;
|
||||
far = right;
|
||||
} else {
|
||||
close = right;
|
||||
far = left;
|
||||
}
|
||||
|
||||
if let Some(close_intersect) = self.intersect_bvh(close, ray, min, max) {
|
||||
if let Some(far_intersect) = self
|
||||
.intersect_bvh(far, ray, min, Float::min(min, close_intersect.1))
|
||||
.filter(|far_intersect| far_intersect.1 < close_intersect.1)
|
||||
{
|
||||
Some(far_intersect)
|
||||
} else {
|
||||
Some(close_intersect)
|
||||
}
|
||||
} else {
|
||||
self.intersect_bvh(far, ray, min, max)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Node::Leaf { start, count } => {
|
||||
let mut intersection = None;
|
||||
for i in start..(start + count) {
|
||||
|
|
@ -148,19 +182,24 @@ impl<R: Rng> Scene<R> for TriangleBVH<R> {
|
|||
let (i, t) = self.intersect_bvh(0, ray, min, max)?;
|
||||
|
||||
let triangle = self.triangles[i as usize];
|
||||
let material = self.materials[triangle.material as usize].as_ref();
|
||||
let material = &self.materials[triangle.material as usize];
|
||||
|
||||
let n = triangle_normal(self.get_vertices(i)).normalize();
|
||||
|
||||
Some(Intersection::new(t, n, material))
|
||||
Some(Intersection::new(
|
||||
t,
|
||||
n,
|
||||
material.material.as_deref(),
|
||||
material.light.as_deref(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub mod examples {
|
||||
use super::{Triangle, TriangleBVH};
|
||||
use super::{BVHMaterial, Triangle, TriangleBVH};
|
||||
use rand::Rng;
|
||||
use ray_tracing_core::material::{AreaLight, DiffuseMaterial};
|
||||
use ray_tracing_core::prelude::*;
|
||||
use ray_tracing_core::{light::AreaLight, prelude::*};
|
||||
use ray_tracing_material::diffuse::DiffuseMaterial;
|
||||
|
||||
pub fn cornel<R: Rng>() -> TriangleBVH<R> {
|
||||
let side_length = 1.5;
|
||||
|
|
@ -196,10 +235,22 @@ pub mod examples {
|
|||
Triangle::new([11, 9, 10], 3),
|
||||
],
|
||||
vec![
|
||||
Box::new(DiffuseMaterial::new(Color::new(0.8, 0.8, 0.8))),
|
||||
Box::new(DiffuseMaterial::new(Color::new(0.9, 0.0, 0.0))),
|
||||
Box::new(DiffuseMaterial::new(Color::new(0.0, 0.9, 0.0))),
|
||||
Box::new(AreaLight::new(Color::new(5.0, 5.0, 5.0))),
|
||||
BVHMaterial {
|
||||
material: Some(Box::new(DiffuseMaterial::new(Color::new(0.8, 0.8, 0.8)))),
|
||||
light: None,
|
||||
},
|
||||
BVHMaterial {
|
||||
material: Some(Box::new(DiffuseMaterial::new(Color::new(0.9, 0.0, 0.0)))),
|
||||
light: None,
|
||||
},
|
||||
BVHMaterial {
|
||||
material: Some(Box::new(DiffuseMaterial::new(Color::new(0.0, 0.9, 0.0)))),
|
||||
light: None,
|
||||
},
|
||||
BVHMaterial {
|
||||
material: None,
|
||||
light: Some(Box::new(AreaLight::new(Color::white() * 30.0))),
|
||||
},
|
||||
],
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue