Add eval to visualizer and fix pbr error
This commit is contained in:
parent
109a72c19a
commit
3a37a72f56
10 changed files with 105 additions and 55 deletions
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "ray-tracing-material-validator"
|
||||
name = "ray-tracing-material-visualizer"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
use ray_tracing_core::color::Color;
|
||||
use ray_tracing_material::{diffuse::DiffuseMaterial, mirror::Mirror};
|
||||
use ray_tracing_material_validator::generate_chart;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let m = Mirror::new(Color::new(1.0, 1.0, 0.5));
|
||||
generate_chart("mirror.png", &m, 2)?;
|
||||
|
||||
let m = DiffuseMaterial::new(Color::new(1.0, 1.0, 0.5));
|
||||
generate_chart("diffuse.png", &m, 100)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1,51 +1,68 @@
|
|||
use plotters::{coord::Shift, prelude::*};
|
||||
use plotters::{
|
||||
chart::ChartBuilder,
|
||||
coord::Shift,
|
||||
prelude::{BitMapBackend, DrawingArea, DrawingBackend, IntoDrawingArea},
|
||||
style::WHITE,
|
||||
};
|
||||
use rand::{rngs::SmallRng, SeedableRng};
|
||||
use ray_tracing_core::{color::Color, prelude::*};
|
||||
use rayon::prelude::*;
|
||||
use ray_tracing_core::prelude::*;
|
||||
use ray_tracing_material::{diffuse::DiffuseMaterial, mirror::Mirror};
|
||||
use rayon::iter::{IntoParallelIterator, ParallelExtend, ParallelIterator};
|
||||
|
||||
pub fn generate_chart<M: Material<SmallRng>>(
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let w_in = Dir3::new(1.0, 1.0, 0.0).normalize();
|
||||
|
||||
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 = DiffuseMaterial::new(color);
|
||||
generate_chart("diffuse.png", &m, 100, w_in)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_chart<M: Material<SmallRng>>(
|
||||
path: impl AsRef<std::path::Path>,
|
||||
m: &M,
|
||||
samples_per_pixel: usize,
|
||||
w_in: Dir3,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let inner_size = 400;
|
||||
let width = (inner_size + 70) * 3 + 34;
|
||||
let height = (inner_size + 97) * 2;
|
||||
let width = (inner_size + 70) * 3;
|
||||
let height = ((inner_size + 97) * 2 + 32) * 2;
|
||||
let root = BitMapBackend::new(&path, (width, height)).into_drawing_area();
|
||||
|
||||
root.fill(&WHITE)?;
|
||||
|
||||
let area = root.titled("Sampled", ("sans-serif", 30))?;
|
||||
plot_material_sample(&area, m, samples_per_pixel)?;
|
||||
let executions = inner_size as usize * inner_size as usize * samples_per_pixel;
|
||||
|
||||
let areas = root.split_evenly((2, 1));
|
||||
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());
|
||||
dbg!(max, eval_histogram.max(), sample_histogram.max());
|
||||
|
||||
let area = areas[0].titled("Evaled", ("sans-serif", 30))?;
|
||||
plot_material(&area, eval_histogram, max)?;
|
||||
|
||||
let area = areas[1].titled("Sampled", ("sans-serif", 30))?;
|
||||
plot_material(&area, sample_histogram, max)?;
|
||||
|
||||
root.present()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn plot_material_sample<DB: DrawingBackend, M: Material<SmallRng>>(
|
||||
fn plot_material<DB: DrawingBackend>(
|
||||
root: &DrawingArea<DB, Shift>,
|
||||
m: &M,
|
||||
samples_per_pixel: usize,
|
||||
histogram: Histogram,
|
||||
max: Float,
|
||||
) -> Result<(), Box<dyn std::error::Error>>
|
||||
where
|
||||
DB::ErrorType: 'static,
|
||||
{
|
||||
let (xrange, yrange) = root.get_pixel_range();
|
||||
let width = (xrange.end - xrange.start) as usize;
|
||||
let height = (yrange.end - yrange.start) as usize;
|
||||
|
||||
let width = width / 3 - 70;
|
||||
let height = height / 2 - 97;
|
||||
|
||||
let histogram = create_historgram(
|
||||
m,
|
||||
width,
|
||||
height,
|
||||
samples_per_pixel * width * height,
|
||||
Dir3::new(1.0, 1.0, 0.0).normalize(),
|
||||
);
|
||||
|
||||
let areas = root.split_evenly((2, 3));
|
||||
for (channel, upper, lower) in (0..3).map(|i| (i, &areas[i], &areas[i + 3])) {
|
||||
let channel_name = match channel {
|
||||
|
|
@ -95,9 +112,17 @@ where
|
|||
|
||||
let lower_area = lower_chart.plotting_area();
|
||||
|
||||
let map = ViridisRGB;
|
||||
let (xrange, yrange) = upper_area.get_pixel_range();
|
||||
let width = (xrange.end - xrange.start) as usize;
|
||||
let height = (yrange.end - yrange.start) as usize;
|
||||
assert_eq!(width, histogram.width);
|
||||
assert_eq!(height, histogram.height);
|
||||
|
||||
let max = histogram.max();
|
||||
let (xrange, yrange) = lower_area.get_pixel_range();
|
||||
let width = (xrange.end - xrange.start) as usize;
|
||||
let height = (yrange.end - yrange.start) as usize;
|
||||
assert_eq!(width, histogram.width);
|
||||
assert_eq!(height, histogram.height);
|
||||
|
||||
for (dir, f) in histogram.iter() {
|
||||
let f = match channel {
|
||||
|
|
@ -107,7 +132,7 @@ where
|
|||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let color = map.get_color_normalized(f, 0.0, max);
|
||||
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)?;
|
||||
} else {
|
||||
|
|
@ -139,10 +164,17 @@ impl Histogram {
|
|||
}
|
||||
|
||||
fn discretize(&self, p: Dir3) -> usize {
|
||||
(((p.x() + 1.0) * 0.5 * self.width as f32).floor() as usize)
|
||||
+ (((p.z() + 1.0) * 0.5 * self.height as f32).floor() as usize) * self.width
|
||||
assert!(p.x() >= -1.0);
|
||||
assert!(p.x() <= 1.0);
|
||||
assert!(p.y() >= -1.0);
|
||||
assert!(p.y() <= 1.0);
|
||||
assert!(p.z() >= -1.0);
|
||||
assert!(p.z() <= 1.0);
|
||||
(((p.x() + 1.0) * 0.5 * self.width as f32).floor() as usize).min(self.width - 1)
|
||||
+ (((p.z() + 1.0) * 0.5 * self.height as f32).floor() as usize).min(self.height - 1)
|
||||
* self.width
|
||||
+ if p.y() < 0.0 {
|
||||
2 * self.width * self.height
|
||||
self.width * self.height
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
|
@ -217,7 +249,7 @@ impl ParallelExtend<(Dir3, Color)> for Histogram {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_historgram<M: Material<SmallRng>>(
|
||||
fn create_historgram_sampled<M: Material<SmallRng>>(
|
||||
m: &M,
|
||||
width: usize,
|
||||
height: usize,
|
||||
|
|
@ -237,3 +269,27 @@ fn create_historgram<M: Material<SmallRng>>(
|
|||
|
||||
h
|
||||
}
|
||||
|
||||
fn create_histogram_evaled<M: Material<SmallRng>>(
|
||||
m: &M,
|
||||
width: usize,
|
||||
height: usize,
|
||||
executions: usize,
|
||||
w_in: Dir3,
|
||||
) -> Histogram {
|
||||
let mut h = Histogram::new(width, height);
|
||||
|
||||
h.par_extend(
|
||||
(0..executions)
|
||||
.into_par_iter()
|
||||
.map_init(SmallRng::from_entropy, |rng, _| {
|
||||
let w_out = Dir3::sample_uniform_sphere(rng);
|
||||
|
||||
let color = m.eval(w_in, w_out, rng) * w_out.y() * 4.0 * FloatConsts::PI;
|
||||
|
||||
(w_out, color)
|
||||
}),
|
||||
);
|
||||
|
||||
h
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue