Fix some Microfacet bugs
This commit is contained in:
parent
745b7d2602
commit
c26285a98e
5 changed files with 119 additions and 29 deletions
27
ray-tracing-material-visualizer/src/bin/fresnel.rs
Normal file
27
ray-tracing-material-visualizer/src/bin/fresnel.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use plotters::prelude::*;
|
||||
use ray_tracing_core::prelude::*;
|
||||
use ray_tracing_material::microfacet::fresnel_real;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let root = BitMapBackend::new("fresnel.png", (640, 480)).into_drawing_area();
|
||||
root.fill(&WHITE)?;
|
||||
let mut chart = ChartBuilder::on(&root)
|
||||
.caption("Fresnel", ("sans-serif", 50).into_font())
|
||||
.margin(5)
|
||||
.x_label_area_size(30)
|
||||
.y_label_area_size(30)
|
||||
.build_cartesian_2d(0.0..FloatConsts::FRAC_PI_2, 0.0..1.0f32)?;
|
||||
|
||||
chart.configure_mesh().draw()?;
|
||||
|
||||
chart.draw_series(LineSeries::new(
|
||||
(0..=300)
|
||||
.map(|x| x as Float * FloatConsts::FRAC_PI_2 / 300.0)
|
||||
.map(|x| (x, fresnel_real(Float::cos(x), 1.0, 1.5))),
|
||||
&RED,
|
||||
))?;
|
||||
|
||||
root.present()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
use core::f64;
|
||||
|
||||
use plotters::{
|
||||
chart::ChartBuilder,
|
||||
coord::Shift,
|
||||
|
|
@ -19,17 +21,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
let color = Color::new(1.0, 1.0, 1.0);
|
||||
|
||||
let m = Mirror::new(color);
|
||||
generate_chart("mirror.png", &m, 2, w_in)?;
|
||||
// let m = Mirror::new(color);
|
||||
// generate_chart("mirror.png", &m, 2, w_in)?;
|
||||
|
||||
let m = DiffuseMaterial::new(color);
|
||||
generate_chart("diffuse.png", &m, 100, w_in)?;
|
||||
// let m = DiffuseMaterial::new(color);
|
||||
// generate_chart("diffuse.png", &m, 100, w_in)?;
|
||||
|
||||
let m = Microfacet::new(BeckmannDistribution::new(0.5), color);
|
||||
generate_chart("microfacet.png", &m, 100, w_in)?;
|
||||
let m = Microfacet::new(BeckmannDistribution::new(0.1), color);
|
||||
generate_chart("microfacet.png", &m, 400, w_in)?;
|
||||
|
||||
let m = OrenNayar::new(0.5, color);
|
||||
generate_chart("oren-nayar.png", &m, 100, w_in)?;
|
||||
// let m = OrenNayar::new(0.5, color);
|
||||
// generate_chart("oren-nayar.png", &m, 100, w_in)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -52,7 +54,10 @@ fn generate_chart<M: Material<SmallRng>>(
|
|||
let eval_histogram = create_histogram_evaled(m, 400, 400, executions, w_in);
|
||||
let sample_histogram = create_historgram_sampled(m, 400, 400, executions, w_in);
|
||||
|
||||
let max = Float::max(eval_histogram.max(), sample_histogram.max());
|
||||
let max = Float::max(
|
||||
Float::max(eval_histogram.max(), sample_histogram.max()),
|
||||
Float::MIN_POSITIVE,
|
||||
);
|
||||
|
||||
let area = areas[0].titled("Evaled", ("sans-serif", 30))?;
|
||||
plot_material(&area, eval_histogram, max)?;
|
||||
|
|
@ -142,7 +147,7 @@ where
|
|||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(f >= 0.0 && f <= max && f.is_finite(), "{f}");
|
||||
assert!(f >= 0.0 && f <= max && f.is_finite() && max != 0.0, "{f}");
|
||||
let color = plotters::prelude::ViridisRGB::get_color_normalized(f, 0.0, max);
|
||||
if dir.y() < 0.0 {
|
||||
lower_area.draw_pixel((dir.x() as f64, dir.z() as f64), &color)?;
|
||||
|
|
@ -160,7 +165,7 @@ struct Histogram {
|
|||
inserted: usize,
|
||||
width: usize,
|
||||
height: usize,
|
||||
max: f32,
|
||||
max: f64,
|
||||
}
|
||||
|
||||
impl Histogram {
|
||||
|
|
@ -194,14 +199,15 @@ impl Histogram {
|
|||
fn insert(&mut self, pos: Dir3, value: Color) {
|
||||
let index = self.discretize(pos);
|
||||
self.data[index] += value;
|
||||
self.max = f32::max(self.max, self.data[index].r());
|
||||
self.max = f32::max(self.max, self.data[index].g());
|
||||
self.max = f32::max(self.max, self.data[index].b());
|
||||
self.max = f64::max(self.max, self.data[index].r() as f64);
|
||||
self.max = f64::max(self.max, self.data[index].g() as f64);
|
||||
self.max = f64::max(self.max, self.data[index].b() as f64);
|
||||
self.inserted += 1;
|
||||
}
|
||||
|
||||
fn max(&self) -> f32 {
|
||||
self.max / (self.inserted as f32)
|
||||
dbg!(self.max, self.inserted, self.inserted as f64);
|
||||
(self.max / (self.inserted as f64)) as f32
|
||||
}
|
||||
|
||||
fn iter(&self) -> impl Iterator<Item = (Dir3, Color)> + use<'_> {
|
||||
|
|
@ -280,8 +286,11 @@ fn create_historgram_sampled<M: Material<SmallRng>>(
|
|||
&& sample.color().g() >= 0.0
|
||||
&& sample.color().g().is_finite()
|
||||
&& sample.color().b() >= 0.0
|
||||
&& sample.color().b().is_finite(),
|
||||
"w_in: {w_in:?}; w_out: {:?}; material: {m:?}; color: {:?}",
|
||||
&& sample.color().b().is_finite()
|
||||
&& (-1.0..=1.0).contains(&sample.w_out().x())
|
||||
&& (-1.0..=1.0).contains(&sample.w_out().y())
|
||||
&& (-1.0..=1.0).contains(&sample.w_out().z()),
|
||||
"invalid_sampling: w_in: {w_in:?}; w_out: {:?}; material: {m:?}; color: {:?}",
|
||||
sample.w_out(),
|
||||
sample.color()
|
||||
);
|
||||
|
|
@ -317,7 +326,7 @@ fn create_histogram_evaled<M: Material<SmallRng>>(
|
|||
&& color.g().is_finite()
|
||||
&& color.b() >= 0.0
|
||||
&& color.b().is_finite(),
|
||||
"w_in: {w_in:?}; w_out: {w_out:?}; material: {m:?}; color: {color:?}"
|
||||
"invalid_eval: w_in: {w_in:?}; w_out: {w_out:?}; material: {m:?}; color: {color:?}"
|
||||
);
|
||||
|
||||
(w_out, color)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue