Fix MIS bugs
This commit is contained in:
parent
27ea5c5d93
commit
908efa79c2
5 changed files with 33 additions and 15 deletions
|
|
@ -8,7 +8,7 @@ pub trait Material<R: Rng>: Send + Sync + Debug {
|
|||
fn sample(&self, w_in: Dir3, rng: &mut R) -> SampleResult {
|
||||
let w_out = Dir3::sample_cosine_hemisphere(rng);
|
||||
|
||||
SampleResult::new(w_out, self.eval(w_in, w_out, rng) * FloatConsts::PI)
|
||||
SampleResult::new(w_out, self.eval(w_in, w_out, rng) * FloatConsts::PI, false)
|
||||
}
|
||||
|
||||
fn pdf(&self, w_in: Dir3, w_out: Dir3) -> Float {
|
||||
|
|
@ -21,11 +21,16 @@ pub trait Material<R: Rng>: Send + Sync + Debug {
|
|||
pub struct SampleResult {
|
||||
w_out: Dir3,
|
||||
color: Color,
|
||||
delta: bool,
|
||||
}
|
||||
|
||||
impl SampleResult {
|
||||
pub fn new(w_out: Dir3, color: Color) -> Self {
|
||||
Self { w_out, color }
|
||||
pub fn new(w_out: Dir3, color: Color, delta: bool) -> Self {
|
||||
Self {
|
||||
w_out,
|
||||
color,
|
||||
delta,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn w_out(&self) -> Dir3 {
|
||||
|
|
@ -35,4 +40,8 @@ impl SampleResult {
|
|||
pub fn color(&self) -> Color {
|
||||
self.color
|
||||
}
|
||||
|
||||
pub fn is_delta(&self) -> bool {
|
||||
self.delta
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,9 +52,10 @@ impl<R: Rng, D: MicrofacetDistribution + Debug + Sync + Send> Material<R> for Mi
|
|||
ray_tracing_core::material::SampleResult::new(
|
||||
w_out,
|
||||
self.color * fresnel_real(Dir3::dot(w_in, w_h), 1.0, 1.5) * g,
|
||||
false,
|
||||
)
|
||||
} else {
|
||||
ray_tracing_core::material::SampleResult::new(w_out, Color::black())
|
||||
ray_tracing_core::material::SampleResult::new(w_out, Color::black(), false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ impl<R: Rng> Material<R> for Mirror {
|
|||
fn sample(&self, w_in: Dir3, _rng: &mut R) -> ray_tracing_core::material::SampleResult {
|
||||
let w_out = (2.0 * Dir3::up() * w_in.y()) - w_in;
|
||||
|
||||
ray_tracing_core::material::SampleResult::new(w_out, self.color)
|
||||
ray_tracing_core::material::SampleResult::new(w_out, self.color, true)
|
||||
}
|
||||
|
||||
fn pdf(&self, w_in: Dir3, w_out: Dir3) -> Float {
|
||||
|
|
|
|||
|
|
@ -36,12 +36,7 @@ where
|
|||
if let Some(light) = i.light() {
|
||||
if count == 0 {
|
||||
sum += alpha * light.emit(w_in, rng);
|
||||
}
|
||||
}
|
||||
|
||||
let w_out = if let Some(material) = i.material() {
|
||||
let sample_result = material.sample(w_in, rng);
|
||||
if let Some(light) = i.light() {
|
||||
} else {
|
||||
let dist = i.t() / r.dir().length();
|
||||
|
||||
let path_pdf = last_bsdf_pdf;
|
||||
|
|
@ -50,6 +45,10 @@ where
|
|||
let b = path_pdf / (path_pdf + nee_pdf);
|
||||
sum += b * alpha * light.emit(w_in, rng);
|
||||
}
|
||||
}
|
||||
|
||||
let w_out = if let Some(material) = i.material() {
|
||||
let sample_result = material.sample(w_in, rng);
|
||||
|
||||
if let Some(l) = scene.sample_light(w_in, &i, rng) {
|
||||
let light_frame = l.tangent_frame();
|
||||
|
|
@ -82,7 +81,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
last_bsdf_pdf = material.pdf(w_in, sample_result.w_out());
|
||||
if sample_result.is_delta() {
|
||||
last_bsdf_pdf = 100000.0;
|
||||
} else {
|
||||
last_bsdf_pdf = material.pdf(w_in, sample_result.w_out());
|
||||
}
|
||||
alpha *= sample_result.color();
|
||||
sample_result.w_out()
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -91,9 +91,14 @@ impl<R: Rng + 'static> ExampleScene<R> for MISTest<R> {
|
|||
|
||||
let area = light_offset * light_offset * 4.0;
|
||||
let material_offset = materials.len() as u32;
|
||||
materials.push(BVHMaterial::new_light(AreaLight::new(
|
||||
Color::white() * 10.0 / area,
|
||||
)));
|
||||
|
||||
let color = match i % 3 {
|
||||
0 => Color::new(1.0, 0.0, 0.0),
|
||||
1 => Color::new(0.0, 1.0, 0.0),
|
||||
2 => Color::new(0.0, 0.0, 1.0),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
materials.push(BVHMaterial::new_light(AreaLight::new(color * 10.0 / area)));
|
||||
|
||||
triangles.extend_from_slice(&[
|
||||
Triangle::new(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue