71 lines
2.2 KiB
Rust
71 lines
2.2 KiB
Rust
use super::state::PathState;
|
|
use crate::core::light::Light;
|
|
use shared::core::geometry::Ray;
|
|
use shared::core::interaction::{Interaction, InteractionTrait};
|
|
use shared::core::primitive::Primitive;
|
|
use shared::core::shape::ShapeIntersection;
|
|
use shared::lights::LightSampler;
|
|
use shared::spectra::SampledWavelengths;
|
|
use shared::utils::sampling::power_heuristic;
|
|
use shared::{Float, SHADOW_EPSILON};
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct IntegratorBase {
|
|
pub aggregate: Arc<Primitive>,
|
|
pub lights: Vec<Arc<Light>>,
|
|
pub infinite_lights: Vec<Arc<Light>>,
|
|
}
|
|
|
|
impl IntegratorBase {
|
|
pub fn new(aggregate: Arc<Primitive>, lights: Vec<Arc<Light>>) -> Self {
|
|
let infinite_lights = lights
|
|
.iter()
|
|
.filter(|light| light.light_type().is_infinite())
|
|
.cloned()
|
|
.collect();
|
|
|
|
Self {
|
|
aggregate,
|
|
lights,
|
|
infinite_lights,
|
|
}
|
|
}
|
|
|
|
pub fn intersect(&self, ray: &Ray, t_max: Option<Float>) -> Option<ShapeIntersection> {
|
|
self.aggregate.intersect(ray, t_max)
|
|
}
|
|
|
|
pub fn intersect_p(&self, ray: &Ray, t_max: Option<Float>) -> bool {
|
|
self.aggregate.intersect_p(ray, t_max)
|
|
}
|
|
|
|
pub fn unoccluded(&self, p0: &Interaction, p1: &Interaction) -> bool {
|
|
!self.intersect_p(&p0.spawn_ray_to_interaction(p1), Some(1. - SHADOW_EPSILON))
|
|
}
|
|
|
|
pub fn add_infinite_light_contribution(
|
|
&self,
|
|
state: &mut PathState,
|
|
ray: &Ray,
|
|
lambda: &SampledWavelengths,
|
|
light_sampler: Option<&LightSampler>,
|
|
use_mis: bool,
|
|
) {
|
|
for light in &self.infinite_lights {
|
|
let le = light.le(ray, lambda);
|
|
if le.is_black() {
|
|
continue;
|
|
}
|
|
|
|
if state.depth == 0 || state.specular_bounce || !use_mis {
|
|
state.l += state.beta * le;
|
|
} else if let Some(sampler) = light_sampler {
|
|
let p_l = sampler.pmf_with_context(&state.prev_ctx, light)
|
|
* light.pdf_li(&state.prev_ctx, ray.d, true);
|
|
let w_b = power_heuristic(1, state.prev_pdf, 1, p_l);
|
|
state.l += state.beta * w_b * le;
|
|
}
|
|
}
|
|
}
|
|
}
|