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
*.ppm
*.jpg
*.png
/*.ppm
/*.jpg
/*.png
flamegraph.svg
perf.data*

View file

@ -1,5 +1,13 @@
# 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
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 b = pixel_color.z();
let scale = 1.0 / samples_per_pixel as f64;
r = (scale * r).sqrt();
g = (scale * g).sqrt();
b = (scale * b).sqrt();
//let scale = 1.0 / samples_per_pixel as f64;
//r = r/samples_per_pixel as f64; //(scale * r).sqrt();
//g = g/samples_per_pixel as f64; //(scale * g).sqrt();
//b = b/samples_per_pixel as f64; //(scale * b).sqrt();
img.put_pixel(
x,

View file

@ -292,33 +292,33 @@ Current world view:
/ z \ x
*/
fn main() {
// File
let mut default_file = "image.ppm";
// Image
let aspect_ratio = 10.0/7.5; //16.0 / 9.0;
let image_width = 1000;
let aspect_ratio = 10.0 / 7.5; //16.0 / 9.0;
let image_width = 400;
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 antialiasing_threshold = 0.3; // at what diff between two colors will a pixel be antialiased
let vfov = 40.0;
let lookfrom = Point3::new(2.0, 0.8, 3.0);
let lookat = Point3::new(0.0, 0.0, 0.0);
let vup = Vec3::new(0.0, 1.0, 0.0);
let dist_to_focus = 3.0;
let aperture = 0.1;
let aperture = 0.0; // disable depth of field
// 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 {
env::set_var("RAYON_NUM_THREADS", thread_count.to_string());
}
// World
eprintln!("[1/3] Loading meshes from file...");
eprintln!("[1/4] Loading meshes from file...");
let world = from_obj("obj/suzanne.obj");
// let world = random_world();
@ -339,7 +339,7 @@ fn main() {
default_file = &args[1];
}
eprintln!("[2/3] Gerenating image...");
eprintln!("[2/4] Generating image...");
let bar = ProgressBar::new(image_height as u64);
let mut image = RgbImage::new(image_width, image_height);
@ -353,20 +353,14 @@ fn main() {
let mut colors = Vec::new();
for i in 0..image_width {
let mut pixel_color = ray_color(
let pixel_color = ray_color(
&cam.get_ray(
i as f64 / (image_width - 1) as f64,
j as f64 / (image_height - 1) as f64,
),
&world,
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);
}
return colors;
@ -374,15 +368,99 @@ fn main() {
.collect();
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_width).into_iter().for_each(|i| {
color::put_color(
&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,
image_height - j - 1,
samples_per_pixel,
1,
);
})
});

View file

@ -17,9 +17,7 @@ pub struct Dielectric {
ir: f64,
}
pub struct Rainbow {
}
pub struct Rainbow {}
pub trait Material: Sync + Send {
fn scatter(
@ -183,10 +181,11 @@ impl Material for Rainbow {
}
*scattered = Ray::new(rec.p, scatter_direction);
let color = 0.5*Color::new(
rec.normal.x()+1.0,
rec.normal.y()+1.0,
rec.normal.z()+1.0
let color = 0.5
* Color::new(
rec.normal.x() + 1.0,
rec.normal.y() + 1.0,
rec.normal.z() + 1.0,
);
*attenuation = color;
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]
}
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 {
Vec3::new(
a.y() * b.z() - a.z() * b.y(),