Add light as associated type for scene and get something to draw with pbrt materials.
This commit is contained in:
parent
b54a2b16fe
commit
bb2089477e
13 changed files with 286 additions and 87 deletions
|
|
@ -5,6 +5,18 @@ pub trait Light<R: Rng>: Send + Sync + Debug {
|
|||
fn emit(&self, w_in: Dir3, rng: &mut R) -> Color;
|
||||
}
|
||||
|
||||
impl<R: Rng> Light<R> for &'_ dyn Light<R> {
|
||||
fn emit(&self, w_in: Dir3, rng: &mut R) -> Color {
|
||||
(*self).emit(w_in, rng)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Rng, L: Light<R>> Light<R> for &L {
|
||||
fn emit(&self, w_in: Dir3, rng: &mut R) -> Color {
|
||||
(*self).emit(w_in, rng)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AreaLight {
|
||||
pub(crate) color: Color,
|
||||
|
|
|
|||
|
|
@ -8,37 +8,43 @@ pub trait Scene<R: Rng> {
|
|||
Self: 'a,
|
||||
R: 'a;
|
||||
|
||||
type Light<'b>: Light<R>
|
||||
where
|
||||
Self: 'b,
|
||||
R: 'b;
|
||||
|
||||
fn intersect(
|
||||
&self,
|
||||
ray: Ray,
|
||||
min: Float,
|
||||
max: Float,
|
||||
) -> Option<Intersection<'_, R, Self::Mat<'_>>>;
|
||||
) -> Option<Intersection<R, Self::Mat<'_>, Self::Light<'_>>>;
|
||||
|
||||
fn sample_light<'b>(
|
||||
&self,
|
||||
w_in: Dir3,
|
||||
intersection: &Intersection<'_, R, Self::Mat<'b>>,
|
||||
intersection: &Intersection<R, Self::Mat<'b>, Self::Light<'b>>,
|
||||
rng: &mut R,
|
||||
) -> Option<LightSample<'_, R>>
|
||||
where
|
||||
Self: 'b;
|
||||
}
|
||||
|
||||
pub struct Intersection<'sc, R: Rng, M: Material<R> + 'sc> {
|
||||
pub struct Intersection<R: Rng, M: Material<R>, L: Light<R>> {
|
||||
t: Float,
|
||||
normal: Dir3,
|
||||
material: Option<M>,
|
||||
light: Option<&'sc dyn Light<R>>,
|
||||
light: Option<L>,
|
||||
light_pdf: Float,
|
||||
r: std::marker::PhantomData<R>,
|
||||
}
|
||||
|
||||
impl<'sc, R: Rng, M: Material<R>> Intersection<'sc, R, M> {
|
||||
impl<R: Rng, M: Material<R>, L: Light<R>> Intersection<R, M, L> {
|
||||
pub fn new(
|
||||
t: Float,
|
||||
normal: Dir3,
|
||||
material: Option<M>,
|
||||
light: Option<&'sc dyn Light<R>>,
|
||||
light: Option<L>,
|
||||
light_pdf: Float,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
|
@ -47,6 +53,7 @@ impl<'sc, R: Rng, M: Material<R>> Intersection<'sc, R, M> {
|
|||
material,
|
||||
light,
|
||||
light_pdf,
|
||||
r: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,8 +69,8 @@ impl<'sc, R: Rng, M: Material<R>> Intersection<'sc, R, M> {
|
|||
self.material.as_ref()
|
||||
}
|
||||
|
||||
pub fn light(&self) -> Option<&'sc dyn Light<R>> {
|
||||
self.light
|
||||
pub fn light(&self) -> Option<&L> {
|
||||
self.light.as_ref()
|
||||
}
|
||||
|
||||
pub fn light_pdf(&self) -> Float {
|
||||
|
|
@ -120,19 +127,25 @@ impl<T: Scene<R> + ?Sized, R: Rng> Scene<R> for Box<T> {
|
|||
T: 'a,
|
||||
R: 'a;
|
||||
|
||||
type Light<'b>
|
||||
= T::Light<'b>
|
||||
where
|
||||
T: 'b,
|
||||
R: 'b;
|
||||
|
||||
fn intersect(
|
||||
&self,
|
||||
ray: Ray,
|
||||
min: Float,
|
||||
max: Float,
|
||||
) -> Option<Intersection<'_, R, Self::Mat<'_>>> {
|
||||
) -> Option<Intersection<R, Self::Mat<'_>, Self::Light<'_>>> {
|
||||
self.deref().intersect(ray, min, max)
|
||||
}
|
||||
|
||||
fn sample_light<'b>(
|
||||
&self,
|
||||
w_in: Dir3,
|
||||
intersection: &Intersection<'_, R, Self::Mat<'b>>,
|
||||
intersection: &Intersection<R, Self::Mat<'b>, Self::Light<'b>>,
|
||||
rng: &mut R,
|
||||
) -> Option<LightSample<'_, R>>
|
||||
where
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue