Add some materials, move some spheres

This commit is contained in:
Jonathan Flueren 2022-06-08 19:53:37 +02:00
parent 15d3a50d16
commit d6e92fa2ba
2 changed files with 52 additions and 18 deletions

View file

@ -19,7 +19,7 @@ use std::env;
use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc; use std::sync::Arc;
use vec3::{Color, Point3, Vec3}; use vec3::{Color, Point3, Vec3};
use material::{Material, Lambertian, Metal}; use material::{Material, Lambertian, Metal, Mirror};
fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color { fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color {
let mut rec = HitRecord::empty(); let mut rec = HitRecord::empty();
@ -50,7 +50,7 @@ fn main() {
// Image // Image
let aspect_ratio = 16.0 / 9.0; let aspect_ratio = 16.0 / 9.0;
let image_width = 1920; let image_width = 1000;
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 = 100_u32;
let max_depth = 50; let max_depth = 50;
@ -60,9 +60,9 @@ fn main() {
let material_ground = Arc::new(Lambertian::new(&Color::new(0.8, 0.8, 0.0))); let material_ground = Arc::new(Lambertian::new(&Color::new(0.8, 0.8, 0.0)));
let material_center = Arc::new(Lambertian::new(&Color::new(0.7, 0.1, 0.2))); let material_center = Arc::new(Lambertian::new(&Color::new(0.7, 0.1, 0.2)));
let material_left = Arc::new(Metal::new(&Color::new(0.8, 0.8, 0.8))); let material_blue = Arc::new(Lambertian::new(&Color::new(0.2, 0.1, 0.7)));
let material_right = Arc::new(Metal::new(&Color::new(0.8, 0.6, 0.2))); let material_metal = Arc::new(Metal::new(&Color::new(0.8, 0.8, 0.8)));
let material_mirror = Arc::new(Metal::new(&Color::new(0.9, 0.9, 0.9))); let _material_mirror = Arc::new(Mirror::new(&Color::new(0.99, 0.99, 0.99)));
@ -72,26 +72,30 @@ fn main() {
material_ground.clone(), material_ground.clone(),
))); )));
world.add(Box::<Sphere>::new(Sphere::new( world.add(Box::<Sphere>::new(Sphere::new(
Point3::new(0.0, 0.0, -1.0), Point3::new(0.0, -0.1, -1.0),
0.5, 0.4,
material_center.clone(), material_center.clone(),
))); )));
world.add(Box::<Sphere>::new(Sphere::new( world.add(Box::<Sphere>::new(Sphere::new(
Point3::new(-1.0, 0.0, -1.0), Point3::new(-1.0, 0.0, -1.0),
0.5, 0.5,
material_mirror.clone(), material_metal.clone(),
))); )));
world.add(Box::<Sphere>::new(Sphere::new( world.add(Box::<Sphere>::new(Sphere::new(
Point3::new(1.0, 0.0, -1.0), Point3::new(1.3, 0.3, -1.5),
0.5, 0.8,
material_mirror.clone(), material_metal.clone(),
))); )));
world.add(Box::<Sphere>::new(Sphere::new( world.add(Box::<Sphere>::new(Sphere::new(
Point3::new(-1.0, 1.1, -1.2), Point3::new(-1.5, 1.3, -1.7),
0.4, 0.4,
material_left.clone(), material_metal.clone(),
)));
world.add(Box::<Sphere>::new(Sphere::new(
Point3::new(-0.5, 0.5, 1.0),
1.0,
material_blue.clone(),
))); )));
/* /*
for i in -15..15 { for i in -15..15 {
for j in -15..15 { for j in -15..15 {

View file

@ -3,6 +3,7 @@ use super::{
HitRecord, HitRecord,
Color, Color,
Vec3, Vec3,
utility,
}; };
pub struct Lambertian { pub struct Lambertian {
@ -13,6 +14,11 @@ pub struct Metal {
albedo: Color, albedo: Color,
} }
pub struct Mirror {
albedo: Color,
}
pub trait Material: Sync + Send { pub trait Material: Sync + Send {
fn scatter(&self,r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool; fn scatter(&self,r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool;
} }
@ -45,10 +51,6 @@ impl Metal {
albedo: *a, albedo: *a,
} }
} }
pub fn clone(&self) -> Self {
Self::new(&self.albedo.clone())
}
} }
impl Material for Metal { impl Material for Metal {
@ -61,3 +63,31 @@ impl Material for Metal {
return Vec3::dot(scattered.direction(), rec.normal) > 0.0; return Vec3::dot(scattered.direction(), rec.normal) > 0.0;
} }
} }
impl Mirror {
pub fn new(a: &Color) -> Self {
Mirror {
albedo: *a,
}
}
}
impl Material for Mirror {
fn scatter(&self, r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
if utility::random_f64() > 0.8 { // Reflektiert
let reflected = Vec3::reflect(&Vec3::unit_vector(r_in.direction()), &rec.normal);
*scattered = Ray::new(rec.p, reflected);
*attenuation = self.albedo.clone();
return Vec3::dot(scattered.direction(), rec.normal) > 0.0;
} else { // Geht geradeaus durch
let reflected = r_in.direction().clone();
*scattered = Ray::new(rec.p, reflected);
*attenuation = self.albedo.clone();
return true;
};
}
}