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
|
|
@ -43,7 +43,7 @@ impl AABB {
|
|||
&& pos.z <= self.max.z
|
||||
}
|
||||
|
||||
pub fn intersect_ray(self, ray: Ray) -> Option<Float> {
|
||||
pub fn intersect_ray(self, ray: Ray, min: Float, max: Float) -> Option<Float> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
pub mod aabb;
|
||||
pub mod camera;
|
||||
pub mod color;
|
||||
pub mod light;
|
||||
pub mod material;
|
||||
pub mod math;
|
||||
pub mod ray;
|
||||
|
|
@ -11,6 +12,7 @@ pub mod prelude {
|
|||
pub type Float = f32;
|
||||
pub use crate::aabb::AABB;
|
||||
pub use crate::color::Color;
|
||||
pub use crate::light::Light;
|
||||
pub use crate::material::Material;
|
||||
pub use crate::math::*;
|
||||
pub use crate::ray::Ray;
|
||||
|
|
|
|||
26
ray-tracing-core/src/light.rs
Normal file
26
ray-tracing-core/src/light.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
use crate::prelude::*;
|
||||
use rand::Rng;
|
||||
|
||||
pub trait Light<R: Rng>: Sync {
|
||||
fn emit(&self, w_in: Dir3, rng: &mut R) -> Color;
|
||||
}
|
||||
|
||||
pub struct AreaLight {
|
||||
pub(crate) color: Color,
|
||||
}
|
||||
|
||||
impl AreaLight {
|
||||
pub fn new(color: Color) -> Self {
|
||||
Self { color }
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Rng> Light<R> for AreaLight {
|
||||
fn emit(&self, w_in: Dir3, _rng: &mut R) -> Color {
|
||||
if w_in.y() > 0.0 {
|
||||
self.color
|
||||
} else {
|
||||
Color::black()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,52 +3,5 @@ use rand::Rng;
|
|||
|
||||
/// All calculations for the material are done a tangent space of the intersection.
|
||||
pub trait Material<R: Rng>: Sync {
|
||||
fn eval(&self, w_in: Dir3, w_out: Dir3, rng: &mut R) -> Option<Color> {
|
||||
None
|
||||
}
|
||||
|
||||
fn emit(&self, w_in: Dir3, rng: &mut R) -> Option<Color> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DefaultMaterial {}
|
||||
|
||||
impl<R: Rng> Material<R> for DefaultMaterial {
|
||||
// evaluates the bsdf
|
||||
fn eval(&self, _w_in: Dir3, _w_out: Dir3, _rng: &mut R) -> Option<Color> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DiffuseMaterial {
|
||||
color: Color,
|
||||
}
|
||||
|
||||
impl DiffuseMaterial {
|
||||
pub fn new(color: Color) -> Self {
|
||||
Self { color }
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Rng> Material<R> for DiffuseMaterial {
|
||||
fn eval(&self, _w_in: Dir3, _w_out: Dir3, _rng: &mut R) -> Option<Color> {
|
||||
Some(self.color)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AreaLight {
|
||||
color: Color,
|
||||
}
|
||||
|
||||
impl AreaLight {
|
||||
pub fn new(color: Color) -> Self {
|
||||
Self { color }
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Rng> Material<R> for AreaLight {
|
||||
fn emit(&self, _w_in: Dir3, _rng: &mut R) -> Option<Color> {
|
||||
Some(self.color)
|
||||
}
|
||||
fn eval(&self, w_in: Dir3, w_out: Dir3, rng: &mut R) -> Color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@ mod test {
|
|||
|
||||
dbg!(f);
|
||||
|
||||
dbg!(f.to_world(Dir3::new(0.0, 1.0, 0.0)));
|
||||
let t = dbg!(f.to_world(Dir3::new(1.0, 1.0, 1.0)));
|
||||
|
||||
dbg!(f.to_frame(t));
|
||||
|
||||
panic!()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,27 +50,25 @@ where
|
|||
let mut count = 0;
|
||||
|
||||
while let Some(i) = self.scene.intersect(r, 0.001, Float::INFINITY) {
|
||||
if count > 4 {
|
||||
break;
|
||||
}
|
||||
let frame = i.tangent_frame();
|
||||
let w_in = frame.to_frame(-r.dir());
|
||||
let w_out = Dir3::generate_uniform_hemisphere(rng);
|
||||
|
||||
let mat = i.material();
|
||||
|
||||
if let Some(c) = mat.emit(w_in, rng) {
|
||||
sum += alpha * c * w_out.y();
|
||||
if let Some(light) = i.light() {
|
||||
sum += alpha * light.emit(w_in, rng) * w_out.y();
|
||||
}
|
||||
|
||||
if let Some(c) = mat.eval(w_in, w_out, rng) {
|
||||
alpha *= c;
|
||||
if let Some(material) = i.material() {
|
||||
alpha *= material.eval(w_in, w_out, rng) * w_out.y();
|
||||
} else {
|
||||
return sum;
|
||||
}
|
||||
|
||||
r = Ray::new(r.at(i.t()), frame.to_world(w_out), r.time());
|
||||
count += 1;
|
||||
if count > 4 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sum
|
||||
|
|
|
|||
|
|
@ -8,15 +8,22 @@ pub trait Scene<R: Rng> {
|
|||
pub struct Intersection<'sc, R: Rng> {
|
||||
t: Float,
|
||||
normal: Dir3,
|
||||
material: &'sc dyn Material<R>,
|
||||
material: Option<&'sc dyn Material<R>>,
|
||||
light: Option<&'sc dyn Light<R>>,
|
||||
}
|
||||
|
||||
impl<'sc, R: Rng> Intersection<'sc, R> {
|
||||
pub fn new(t: Float, normal: Dir3, material: &'sc dyn Material<R>) -> Self {
|
||||
pub fn new(
|
||||
t: Float,
|
||||
normal: Dir3,
|
||||
material: Option<&'sc dyn Material<R>>,
|
||||
light: Option<&'sc dyn Light<R>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
t,
|
||||
normal,
|
||||
material,
|
||||
light,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -28,10 +35,14 @@ impl<'sc, R: Rng> Intersection<'sc, R> {
|
|||
self.normal
|
||||
}
|
||||
|
||||
pub fn material(&self) -> &'sc dyn Material<R> {
|
||||
pub fn material(&self) -> Option<&'sc dyn Material<R>> {
|
||||
self.material
|
||||
}
|
||||
|
||||
pub fn light(&self) -> Option<&'sc dyn Light<R>> {
|
||||
self.light
|
||||
}
|
||||
|
||||
pub fn tangent_frame(&self) -> Frame {
|
||||
Frame::from_normal(self.normal)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue