Add images

This commit is contained in:
Jonathan Flueren 2022-08-02 18:30:39 +02:00
parent c787724541
commit bfa58c6962
14 changed files with 124 additions and 35 deletions

6
.gitignore vendored
View file

@ -1,6 +1,6 @@
/target /target
*.ppm /*.ppm
*.jpg /*.jpg
*.png /*.png
flamegraph.svg flamegraph.svg
perf.data* perf.data*

View file

@ -1,5 +1,13 @@
# Renderer - Grafik-AG # Renderer - Grafik-AG
Following [Raytracing In One Weekend](https://raytracing.github.io/books/RayTracingInOneWeekend.html).
Rendered images in `images/`.
![RaytracingInOneWeekend](images/RayTracingInOneWeekend2.png)
![Suzanne Rainbow](images/suzanne_rainbow.png)
*** ***
### Performance analysis with Flamegraph ### Performance analysis with Flamegraph
https://github.com/flamegraph-rs/flamegraph https://github.com/flamegraph-rs/flamegraph

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 KiB

BIN
images/cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 KiB

BIN
images/suzanne_rainbow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

BIN
images/suzanne_rainbow2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 KiB

View file

@ -5,10 +5,10 @@ pub fn put_color(img: &mut RgbImage, pixel_color: &Color, x: u32, y: u32, sample
let mut g = pixel_color.y(); let mut g = pixel_color.y();
let mut b = pixel_color.z(); let mut b = pixel_color.z();
let scale = 1.0 / samples_per_pixel as f64; //let scale = 1.0 / samples_per_pixel as f64;
r = (scale * r).sqrt(); //r = r/samples_per_pixel as f64; //(scale * r).sqrt();
g = (scale * g).sqrt(); //g = g/samples_per_pixel as f64; //(scale * g).sqrt();
b = (scale * b).sqrt(); //b = b/samples_per_pixel as f64; //(scale * b).sqrt();
img.put_pixel( img.put_pixel(
x, x,

View file

@ -292,33 +292,33 @@ Current world view:
/ z \ x / z \ x
*/ */
fn main() { fn main() {
// File // File
let mut default_file = "image.ppm"; let mut default_file = "image.ppm";
// Image // Image
let aspect_ratio = 10.0/7.5; //16.0 / 9.0; let aspect_ratio = 10.0 / 7.5; //16.0 / 9.0;
let image_width = 1000; let image_width = 400;
let image_height = (image_width as f64 / aspect_ratio) as u32; let image_height = (image_width as f64 / aspect_ratio) as u32;
let samples_per_pixel = 100_u32; let samples_per_pixel = 50_u32;
let max_depth = 50; let max_depth = 50;
let antialiasing_threshold = 0.3; // at what diff between two colors will a pixel be antialiased
let vfov = 40.0; let vfov = 40.0;
let lookfrom = Point3::new(2.0, 0.8, 3.0); let lookfrom = Point3::new(2.0, 0.8, 3.0);
let lookat = Point3::new(0.0, 0.0, 0.0); let lookat = Point3::new(0.0, 0.0, 0.0);
let vup = Vec3::new(0.0, 1.0, 0.0); let vup = Vec3::new(0.0, 1.0, 0.0);
let dist_to_focus = 3.0; let dist_to_focus = 3.0;
let aperture = 0.1; let aperture = 0.0; // disable depth of field
// limit rayon multithreading thread count // limit rayon multithreading thread count
let thread_count = 6; // if 0, for each logical cpu core a thread wil be created let thread_count = 4; // if 0, for each logical cpu core a thread wil be created
if thread_count > 0 { if thread_count > 0 {
env::set_var("RAYON_NUM_THREADS", thread_count.to_string()); env::set_var("RAYON_NUM_THREADS", thread_count.to_string());
} }
// World // World
eprintln!("[1/3] Loading meshes from file..."); eprintln!("[1/4] Loading meshes from file...");
let world = from_obj("obj/suzanne.obj"); let world = from_obj("obj/suzanne.obj");
// let world = random_world(); // let world = random_world();
@ -339,7 +339,7 @@ fn main() {
default_file = &args[1]; default_file = &args[1];
} }
eprintln!("[2/3] Gerenating image..."); eprintln!("[2/4] Generating image...");
let bar = ProgressBar::new(image_height as u64); let bar = ProgressBar::new(image_height as u64);
let mut image = RgbImage::new(image_width, image_height); let mut image = RgbImage::new(image_width, image_height);
@ -353,20 +353,14 @@ fn main() {
let mut colors = Vec::new(); let mut colors = Vec::new();
for i in 0..image_width { for i in 0..image_width {
let mut pixel_color = ray_color( let pixel_color = ray_color(
&cam.get_ray( &cam.get_ray(
i as f64 / (image_width - 1) as f64, i as f64 / (image_width - 1) as f64,
j as f64 / (image_height - 1) as f64, j as f64 / (image_height - 1) as f64,
), ),
&world, &world,
max_depth, max_depth,
); // first ray not antialiased to disable antialiasing on value 1 );
for _ in 1..samples_per_pixel {
let u = (i as f64 + utility::random_f64()) / (image_width - 1) as f64;
let v = (j as f64 + utility::random_f64()) / (image_height - 1) as f64;
let r = cam.get_ray(u, v);
pixel_color += ray_color(&r, &world, max_depth);
}
colors.push(pixel_color); colors.push(pixel_color);
} }
return colors; return colors;
@ -374,15 +368,99 @@ fn main() {
.collect(); .collect();
bar.finish_and_clear(); bar.finish_and_clear();
eprintln!("[3/3] Exporting image to disk..."); eprintln!("[3/4] Antialiasing image...");
let mut antialiasing: Vec<Vec<bool>> = Vec::new();
let mut antialiasing_counter = 0;
let mut antialiasing_col_counter = 0;
let mut antialiases_per_line: Vec<u64> = Vec::new();
(0..image_height).into_iter().for_each(|j| {
antialiasing.push(Vec::new());
(0..image_width).into_iter().for_each(|i| {
if j != 0
&& Color::diff(
&color_lines[(j - 1) as usize][i as usize],
&color_lines[j as usize][i as usize],
) >= antialiasing_threshold
{
antialiasing[j as usize].push(true);
antialiasing_col_counter += 1;
} else if j != image_height - 1
&& Color::diff(
&color_lines[(j + 1) as usize][i as usize],
&color_lines[j as usize][i as usize],
) >= antialiasing_threshold
{
antialiasing[j as usize].push(true);
antialiasing_col_counter += 1;
} else if i != 0
&& Color::diff(
&color_lines[j as usize][(i - 1) as usize],
&color_lines[j as usize][i as usize],
) >= antialiasing_threshold
{
antialiasing[j as usize].push(true);
antialiasing_col_counter += 1;
} else if i != image_width - 1
&& Color::diff(
&color_lines[j as usize][(i + 1) as usize],
&color_lines[j as usize][i as usize],
) >= antialiasing_threshold
{
antialiasing[j as usize].push(true);
antialiasing_col_counter += 1;
}
if antialiasing[j as usize].len() < (i + 1) as usize {
antialiasing[j as usize].push(false);
}
});
antialiases_per_line.push(antialiasing_col_counter);
antialiasing_counter += antialiasing_col_counter;
antialiasing_col_counter = 0;
});
let bar = ProgressBar::new(antialiasing_counter as u64);
let color_lines_antialiased: Vec<_> = (0..image_height)
.into_par_iter() // threadded/parallel variant
//.into_iter() // iterative variant
.map(|j| {
let mut colors = Vec::new();
for i in 0..image_width {
if samples_per_pixel > 0 && antialiasing[j as usize][i as usize] {
let mut pixel_color = Color::null();
for _ in 0..samples_per_pixel {
let u = (i as f64 + utility::random_f64()) / (image_width - 1) as f64;
let v = (j as f64 + utility::random_f64()) / (image_height - 1) as f64;
let r = cam.get_ray(u, v);
dbg!(ray_color(&r, &world, max_depth));
pixel_color += ray_color(&r, &world, max_depth);
}
// Correct antialiasing gamma
pixel_color = Color::new(
pixel_color.x() / samples_per_pixel as f64,
pixel_color.y() / samples_per_pixel as f64,
pixel_color.z() / samples_per_pixel as f64,
);
println!("x: {}, y: {}, z: {}", pixel_color.x(), pixel_color.y(), pixel_color.z());
colors.push(pixel_color);
} else {
colors.push(color_lines[j as usize][i as usize]);
}
}
bar.inc(antialiases_per_line[j as usize]);
return colors;
})
.collect();
bar.finish_and_clear();
eprintln!("[4/4] Exporting image to disk...");
(0..image_height).into_iter().rev().for_each(|j| { (0..image_height).into_iter().rev().for_each(|j| {
(0..image_width).into_iter().for_each(|i| { (0..image_width).into_iter().for_each(|i| {
color::put_color( color::put_color(
&mut image, &mut image,
&color_lines[(image_height - j - 1) as usize][i as usize], &color_lines_antialiased[(image_height - j - 1) as usize][i as usize],
i, i,
image_height - j - 1, image_height - j - 1,
samples_per_pixel, 1,
); );
}) })
}); });

View file

@ -17,9 +17,7 @@ pub struct Dielectric {
ir: f64, ir: f64,
} }
pub struct Rainbow { pub struct Rainbow {}
}
pub trait Material: Sync + Send { pub trait Material: Sync + Send {
fn scatter( fn scatter(
@ -183,11 +181,12 @@ impl Material for Rainbow {
} }
*scattered = Ray::new(rec.p, scatter_direction); *scattered = Ray::new(rec.p, scatter_direction);
let color = 0.5*Color::new( let color = 0.5
rec.normal.x()+1.0, * Color::new(
rec.normal.y()+1.0, rec.normal.x() + 1.0,
rec.normal.z()+1.0 rec.normal.y() + 1.0,
); rec.normal.z() + 1.0,
);
*attenuation = color; *attenuation = color;
return true; return true;
} }

View file

@ -30,6 +30,10 @@ impl Vec3 {
self.e[0] * self.e[0] + self.e[1] * self.e[1] + self.e[2] * self.e[2] self.e[0] * self.e[0] + self.e[1] * self.e[1] + self.e[2] * self.e[2]
} }
pub fn diff(a: &Self, b: &Self) -> f64 {
(a.x() - b.x()).abs() + (a.y() - b.y()).abs() + (a.z() - b.z()).abs()
}
pub fn cross(a: Vec3, b: Vec3) -> Vec3 { pub fn cross(a: Vec3, b: Vec3) -> Vec3 {
Vec3::new( Vec3::new(
a.y() * b.z() - a.z() * b.y(), a.y() * b.z() - a.z() * b.y(),