some refactoring and proper DoF support
All checks were successful
Build & Test / build (push) Successful in 32s
All checks were successful
Build & Test / build (push) Successful in 32s
This commit is contained in:
@@ -6,7 +6,7 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.7.0"
|
rand = "0.10.0"
|
||||||
rayon = "1.8"
|
rayon = "1.8"
|
||||||
image = "0.25.9"
|
image = "0.25.9"
|
||||||
indicatif = "0.18.3"
|
indicatif = "0.18.4"
|
||||||
BIN
example.png
BIN
example.png
Binary file not shown.
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::hittable::Hittable;
|
||||||
use crate::ray::Ray;
|
use crate::ray::Ray;
|
||||||
use crate::rtweekend::degrees_to_radians;
|
use crate::rtweekend::degrees_to_radians;
|
||||||
use crate::vec3::*;
|
use crate::vec3::*;
|
||||||
@@ -9,8 +10,7 @@ pub struct Camera {
|
|||||||
vertical: Vec3,
|
vertical: Vec3,
|
||||||
u: Vec3,
|
u: Vec3,
|
||||||
v: Vec3,
|
v: Vec3,
|
||||||
w: Vec3,
|
lens_radius: f64,
|
||||||
lens_radius: f64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Camera {
|
impl Camera {
|
||||||
@@ -18,13 +18,15 @@ impl Camera {
|
|||||||
lookfrom: Point3,
|
lookfrom: Point3,
|
||||||
lookat: Point3,
|
lookat: Point3,
|
||||||
vup: Vec3,
|
vup: Vec3,
|
||||||
vfov: f64,
|
focal_length_mm: f64,
|
||||||
aspect_ratio: f64,
|
aspect_ratio: f64,
|
||||||
apeture: f64,
|
defocus_angle: f64,
|
||||||
focus_dist: f64,
|
focus_dist: f64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let theta = degrees_to_radians(vfov);
|
let sensor_height = 24.0; // in mm
|
||||||
let h = f64::tan(theta/2.0);
|
let theta = 2.0 * f64::atan(sensor_height / (2.0 * focal_length_mm));
|
||||||
|
|
||||||
|
let h = f64::tan(theta / 2.0);
|
||||||
let viewport_height = 2.0 * h;
|
let viewport_height = 2.0 * h;
|
||||||
let viewport_width = aspect_ratio * viewport_height;
|
let viewport_width = aspect_ratio * viewport_height;
|
||||||
|
|
||||||
@@ -35,20 +37,57 @@ impl Camera {
|
|||||||
let origin = lookfrom;
|
let origin = lookfrom;
|
||||||
let horizontal = focus_dist * viewport_width * u;
|
let horizontal = focus_dist * viewport_width * u;
|
||||||
let vertical = focus_dist * viewport_height * v;
|
let vertical = focus_dist * viewport_height * v;
|
||||||
let lower_left_corner = origin - horizontal/2.0 - vertical/2.0 - focus_dist * w;
|
let lower_left_corner = origin - horizontal / 2.0 - vertical / 2.0 - focus_dist * w;
|
||||||
|
|
||||||
let lens_radius = apeture / 2.0;
|
let defocus_theta = degrees_to_radians(defocus_angle);
|
||||||
|
let lens_radius = focus_dist * f64::tan(defocus_theta / 2.0);
|
||||||
|
|
||||||
Camera { origin, lower_left_corner, horizontal, vertical, u, v, w, lens_radius}
|
Camera {
|
||||||
|
origin,
|
||||||
|
lower_left_corner,
|
||||||
|
horizontal,
|
||||||
|
vertical,
|
||||||
|
u,
|
||||||
|
v,
|
||||||
|
lens_radius,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ray(&self, s: f64, t: f64) -> Ray {
|
pub fn get_ray(&self, s: f64, t: f64) -> Ray {
|
||||||
let rd = self.lens_radius * random_in_unit_disk();
|
let rd = self.lens_radius * random_in_unit_disk();
|
||||||
let offset = self.u * rd.x() + self.v * rd.y();
|
let offset = self.u * rd.x() + self.v * rd.y();
|
||||||
|
|
||||||
|
let ray_origin = self.origin + offset;
|
||||||
|
|
||||||
Ray {
|
Ray {
|
||||||
origin: self.origin,
|
origin: ray_origin,
|
||||||
direction: self.lower_left_corner + s*self.horizontal + t*self.vertical - self.origin - offset
|
direction: self.lower_left_corner + s * self.horizontal + t * self.vertical
|
||||||
|
- ray_origin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
pub fn ray_color(&self, r: Ray, world: &dyn Hittable, depth: i32) -> Color {
|
||||||
|
// Limit the bounces
|
||||||
|
if depth <= 0 {
|
||||||
|
return Color::new(0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(rec) = world.hit(&r, 0.001, f64::INFINITY) {
|
||||||
|
let mut scattered = Ray::new_empty();
|
||||||
|
let mut attenuation = Color::new_empty();
|
||||||
|
|
||||||
|
if rec
|
||||||
|
.material
|
||||||
|
.scatter(r, rec, &mut attenuation, &mut scattered)
|
||||||
|
{
|
||||||
|
return attenuation * Self::ray_color(&self, scattered, world, depth - 1);
|
||||||
|
}
|
||||||
|
return Color::new_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
let unit_direction: Vec3 = r.direction().unit_vector();
|
||||||
|
let t = 0.5 * (unit_direction.y() + 1.0);
|
||||||
|
|
||||||
|
((1.0 - t) * Color::new(1.0, 1.0, 1.0)) + (t * Color::new(0.5, 0.7, 1.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ use crate::vec3::*;
|
|||||||
pub struct HitRecord<'a> {
|
pub struct HitRecord<'a> {
|
||||||
pub p: Point3,
|
pub p: Point3,
|
||||||
pub normal: Vec3,
|
pub normal: Vec3,
|
||||||
pub mat_ptr: &'a dyn Material,
|
pub material: &'a dyn Material,
|
||||||
pub t: f64,
|
pub t: f64,
|
||||||
pub front_face: bool,
|
pub front_face: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HitRecord<'_> {
|
impl HitRecord<'_> {
|
||||||
pub fn new_empty<T: Material>(material: &'static T) -> Self {
|
pub fn new_empty<T: Material>(material: &'static T) -> Self {
|
||||||
HitRecord { p: Point3::new(0.0, 0.0, 0.0), normal: Vec3::new(0.0, 0.0, 0.0), t: 0.0, front_face: false, mat_ptr: material }
|
HitRecord { p: Point3::new(0.0, 0.0, 0.0), normal: Vec3::new(0.0, 0.0, 0.0), t: 0.0, front_face: false, material: material }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_face_normal(&mut self, r: &Ray, outward_normal: Vec3) {
|
pub fn set_face_normal(&mut self, r: &Ray, outward_normal: Vec3) {
|
||||||
|
|||||||
143
src/main.rs
143
src/main.rs
@@ -17,7 +17,6 @@ use rayon::prelude::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
camera::*,
|
camera::*,
|
||||||
color::*,
|
color::*,
|
||||||
hittable::*,
|
|
||||||
hittable_list::*,
|
hittable_list::*,
|
||||||
material::*,
|
material::*,
|
||||||
material::{Dielectric, Lambertian},
|
material::{Dielectric, Lambertian},
|
||||||
@@ -27,7 +26,8 @@ use crate::{
|
|||||||
vec3::*,
|
vec3::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn random_scene() -> HittableList {
|
#[allow(dead_code)]
|
||||||
|
fn random_scene(aspect_ratio: f64) -> (Camera, HittableList) {
|
||||||
let mut world = HittableList::new_empty();
|
let mut world = HittableList::new_empty();
|
||||||
|
|
||||||
let ground_material: Lambertian = Lambertian::new(Color::new(0.5, 0.5, 0.5));
|
let ground_material: Lambertian = Lambertian::new(Color::new(0.5, 0.5, 0.5));
|
||||||
@@ -47,16 +47,28 @@ fn random_scene() -> HittableList {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (center - Point3::new(4.0, 0.2, 0.0)).length() > 0.9 {
|
if (center - Point3::new(4.0, 0.2, 0.0)).length() > 0.9 {
|
||||||
if choose_mat < 0.8 {
|
if choose_mat < 0.3 {
|
||||||
//let albedo = Color::new(0.3, 0.8, 0.4);
|
//let albedo = Color::new(0.3, 0.8, 0.4);
|
||||||
let sphere_material: Lambertian = Lambertian::new(Color::random());
|
let sphere_material: Lambertian = Lambertian::new(Color::random());
|
||||||
world.add(Box::new(Sphere::new(center, 0.2, Box::new(sphere_material))));
|
world.add(Box::new(Sphere::new(
|
||||||
} else if choose_mat < 0.95 {
|
center,
|
||||||
|
0.2,
|
||||||
|
Box::new(sphere_material),
|
||||||
|
)));
|
||||||
|
} else if choose_mat < 0.7 {
|
||||||
let sphere_material: Metal = Metal::new(Color::random(), 0.2);
|
let sphere_material: Metal = Metal::new(Color::random(), 0.2);
|
||||||
world.add(Box::new(Sphere::new(center, 0.2, Box::new(sphere_material))));
|
world.add(Box::new(Sphere::new(
|
||||||
|
center,
|
||||||
|
0.2,
|
||||||
|
Box::new(sphere_material),
|
||||||
|
)));
|
||||||
} else {
|
} else {
|
||||||
let sphere_material: Dielectric = Dielectric::new(1.5);
|
let sphere_material: Dielectric = Dielectric::new(1.5);
|
||||||
world.add(Box::new(Sphere::new(center, 0.2, Box::new(sphere_material))));
|
world.add(Box::new(Sphere::new(
|
||||||
|
center,
|
||||||
|
0.2,
|
||||||
|
Box::new(sphere_material),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,32 +95,85 @@ fn random_scene() -> HittableList {
|
|||||||
Box::new(material3),
|
Box::new(material3),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
world
|
// Camera
|
||||||
|
let lookfrom = Point3::new(13.0, 2.0, 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 = (lookfrom - lookat).length();
|
||||||
|
let focal_length = 50.0;
|
||||||
|
let defocus_angle = 1.;
|
||||||
|
|
||||||
|
let cam = Camera::new(
|
||||||
|
lookfrom,
|
||||||
|
lookat,
|
||||||
|
vup,
|
||||||
|
focal_length,
|
||||||
|
aspect_ratio,
|
||||||
|
defocus_angle,
|
||||||
|
dist_to_focus,
|
||||||
|
);
|
||||||
|
|
||||||
|
(cam, world)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ray_color(r: Ray, world: &dyn Hittable, depth: i32) -> Color {
|
#[allow(dead_code)]
|
||||||
// Limit the bounces
|
fn three_balls_scene(aspect_ratio: f64) -> (Camera, HittableList) {
|
||||||
if depth <= 0 {
|
let mut world = HittableList::new_empty();
|
||||||
return Color::new(0.0, 0.0, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(rec) = world.hit(&r, 0.001, INFINITY) {
|
let material_ground: Lambertian = Lambertian::new(Color::new(0.8, 0.8, 0.0));
|
||||||
let mut scattered = Ray::new_empty();
|
world.add(Box::new(Sphere::new(
|
||||||
let mut attenuation = Color::new_empty();
|
Point3::new(0.0, -100.5, -1.0),
|
||||||
|
100.0,
|
||||||
|
Box::new(material_ground),
|
||||||
|
)));
|
||||||
|
|
||||||
if rec
|
let material_center = Lambertian::new(Color::new(0.1, 0.2, 0.5));
|
||||||
.mat_ptr
|
world.add(Box::new(Sphere::new(
|
||||||
.scatter(r, rec, &mut attenuation, &mut scattered)
|
Point3::new(0.0, 0.0, -1.2),
|
||||||
{
|
0.5,
|
||||||
return attenuation * ray_color(scattered, world, depth - 1);
|
Box::new(material_center),
|
||||||
}
|
)));
|
||||||
return Color::new_empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
let unit_direction: Vec3 = r.direction().unit_vector();
|
let material_left = Dielectric::new(1.5);
|
||||||
let t = 0.5 * (unit_direction.y() + 1.0);
|
world.add(Box::new(Sphere::new(
|
||||||
|
Point3::new(-1.0, 0.0, -1.0),
|
||||||
|
0.5,
|
||||||
|
Box::new(material_left),
|
||||||
|
)));
|
||||||
|
|
||||||
((1.0 - t) * Color::new(1.0, 1.0, 1.0)) + (t * Color::new(0.5, 0.7, 1.0))
|
let material_bubble = Dielectric::new(1.0 / 1.5);
|
||||||
|
world.add(Box::new(Sphere::new(
|
||||||
|
Point3::new(-1.0, 0.0, -1.0),
|
||||||
|
0.4,
|
||||||
|
Box::new(material_bubble),
|
||||||
|
)));
|
||||||
|
|
||||||
|
let material_right = Metal::new(Color::new(0.8, 0.6, 0.2), 1.0);
|
||||||
|
world.add(Box::new(Sphere::new(
|
||||||
|
Point3::new(1.0, 0.0, -1.0),
|
||||||
|
0.5,
|
||||||
|
Box::new(material_right),
|
||||||
|
)));
|
||||||
|
|
||||||
|
// Camera
|
||||||
|
let lookfrom = Point3::new(-2.0, 2.0, 1.0);
|
||||||
|
let lookat = Point3::new(0.0, 0.0, -1.0);
|
||||||
|
let vup = Vec3::new(0.0, 1.0, 0.0);
|
||||||
|
let dist_to_focus = 10.0; //(lookfrom - lookat).length_squared();
|
||||||
|
let vfov = 20.0;
|
||||||
|
let defocus_angle = 0.0;
|
||||||
|
|
||||||
|
let cam = Camera::new(
|
||||||
|
lookfrom,
|
||||||
|
lookat,
|
||||||
|
vup,
|
||||||
|
vfov,
|
||||||
|
aspect_ratio,
|
||||||
|
defocus_angle,
|
||||||
|
dist_to_focus,
|
||||||
|
);
|
||||||
|
|
||||||
|
(cam, world)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -117,26 +182,10 @@ fn main() {
|
|||||||
let image_width: i32 = 1920;
|
let image_width: i32 = 1920;
|
||||||
let image_height: i32 = (image_width as f64 / aspect_ratio as f64) as i32;
|
let image_height: i32 = (image_width as f64 / aspect_ratio as f64) as i32;
|
||||||
let samples_per_pixel: i32 = 200;
|
let samples_per_pixel: i32 = 200;
|
||||||
let max_depth: i32 = 5;
|
let max_depth: i32 = 10;
|
||||||
|
|
||||||
// World
|
// Camera and World
|
||||||
let world = random_scene();
|
let (cam, world) = random_scene(aspect_ratio);
|
||||||
|
|
||||||
// Camera
|
|
||||||
let lookfrom = Point3::new(13.0, 2.0, 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 = 10.0; //(lookfrom-lookat).length_squared();
|
|
||||||
|
|
||||||
let cam = Camera::new(
|
|
||||||
lookfrom,
|
|
||||||
lookat,
|
|
||||||
vup,
|
|
||||||
30.0,
|
|
||||||
aspect_ratio,
|
|
||||||
0.0,
|
|
||||||
dist_to_focus,
|
|
||||||
);
|
|
||||||
|
|
||||||
let num_threads: usize = match available_parallelism() {
|
let num_threads: usize = match available_parallelism() {
|
||||||
Ok(threads) => threads.into(),
|
Ok(threads) => threads.into(),
|
||||||
@@ -174,7 +223,7 @@ fn main() {
|
|||||||
let u = (x as f64 + random_f64()) / (image_width - 1) as f64;
|
let u = (x as f64 + random_f64()) / (image_width - 1) as f64;
|
||||||
let v = (reversed_y as f64 + random_f64()) / (image_height - 1) as f64;
|
let v = (reversed_y as f64 + random_f64()) / (image_height - 1) as f64;
|
||||||
let r = cam.get_ray(u, v);
|
let r = cam.get_ray(u, v);
|
||||||
pixel_color += ray_color(r, &world, max_depth);
|
pixel_color += cam.ray_color(r, &world, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (ir, ig, ib) = get_scaled_color_components(pixel_color, samples_per_pixel);
|
let (ir, ig, ib) = get_scaled_color_components(pixel_color, samples_per_pixel);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::hittable::HitRecord;
|
use crate::hittable::HitRecord;
|
||||||
use crate::ray::Ray;
|
use crate::ray::Ray;
|
||||||
use crate::rtweekend::random_f64;
|
use crate::rtweekend::random_f64;
|
||||||
use crate::vec3::{Color, random_unit_vector, reflect, refract};
|
use crate::vec3::{random_unit_vector, reflect, refract, Color};
|
||||||
|
|
||||||
//More rusty
|
//More rusty
|
||||||
/*
|
/*
|
||||||
@@ -15,9 +15,14 @@ use crate::vec3::{Color, random_unit_vector, reflect, refract};
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
pub trait Material: Send + Sync {
|
pub trait Material: Send + Sync {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Lambertian {
|
pub struct Lambertian {
|
||||||
@@ -31,7 +36,13 @@ impl Lambertian {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Material for Lambertian {
|
impl Material for Lambertian {
|
||||||
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 {
|
||||||
let mut scatter_direction = rec.normal + random_unit_vector();
|
let mut scatter_direction = rec.normal + random_unit_vector();
|
||||||
|
|
||||||
if scatter_direction.near_zero() {
|
if scatter_direction.near_zero() {
|
||||||
@@ -56,9 +67,16 @@ impl Metal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Material for Metal {
|
impl Material for Metal {
|
||||||
fn scatter(&self, r_in: Ray, rec: HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
|
fn scatter(
|
||||||
let reflected = reflect(&r_in.direction(), &rec.normal);
|
&self,
|
||||||
*scattered = Ray::new(rec.p, reflected + self.fuzz*random_unit_vector());
|
r_in: Ray,
|
||||||
|
rec: HitRecord,
|
||||||
|
attenuation: &mut Color,
|
||||||
|
scattered: &mut Ray,
|
||||||
|
) -> bool {
|
||||||
|
let mut reflected = reflect(&r_in.direction(), &rec.normal);
|
||||||
|
reflected = reflected.unit_vector() + (self.fuzz * random_unit_vector());
|
||||||
|
*scattered = Ray::new(rec.p, reflected + self.fuzz * random_unit_vector());
|
||||||
*attenuation = self.albedo;
|
*attenuation = self.albedo;
|
||||||
|
|
||||||
scattered.direction().dot(&rec.normal) > 0.0
|
scattered.direction().dot(&rec.normal) > 0.0
|
||||||
@@ -76,29 +94,37 @@ impl Dielectric {
|
|||||||
|
|
||||||
fn reflectance(&self, cosine: f64, ref_idx: f64) -> f64 {
|
fn reflectance(&self, cosine: f64, ref_idx: f64) -> f64 {
|
||||||
// Schlick
|
// Schlick
|
||||||
let mut r0 = (1.0-ref_idx) / (1.0+ref_idx);
|
let mut r0 = (1.0 - ref_idx) / (1.0 + ref_idx);
|
||||||
r0 = r0*r0;
|
r0 = r0 * r0;
|
||||||
|
|
||||||
return r0 + (1.0-r0)*f64::powf(1.0 - cosine, 5.0);
|
return r0 + (1.0 - r0) * f64::powf(1.0 - cosine, 5.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Material for Dielectric {
|
impl Material for Dielectric {
|
||||||
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 {
|
||||||
*attenuation = Color::new(1.0, 1.0, 1.0);
|
*attenuation = Color::new(1.0, 1.0, 1.0);
|
||||||
let refraction_ratio: f64 = if rec.front_face {
|
let refraction_ratio: f64 = if rec.front_face {
|
||||||
1.0/self.ir
|
1.0 / self.ir
|
||||||
} else {
|
} else {
|
||||||
self.ir
|
self.ir
|
||||||
};
|
};
|
||||||
|
|
||||||
let unit_direction = r_in.direction().unit_vector();
|
let unit_direction = r_in.direction().unit_vector();
|
||||||
let cos_theta = f64::min(-unit_direction.dot(&rec.normal), 1.0);
|
let cos_theta = f64::min(-unit_direction.dot(&rec.normal), 1.0);
|
||||||
let sin_theta = f64::sqrt(1.0 - cos_theta*cos_theta);
|
let sin_theta = f64::sqrt(1.0 - cos_theta * cos_theta);
|
||||||
|
|
||||||
let cannot_refract = (refraction_ratio * sin_theta )> 1.0;
|
let cannot_refract = (refraction_ratio * sin_theta) > 1.0;
|
||||||
|
|
||||||
let direction = if cannot_refract || Dielectric::reflectance(self, cos_theta, refraction_ratio) > random_f64() {
|
let direction = if cannot_refract
|
||||||
|
|| Dielectric::reflectance(self, cos_theta, refraction_ratio) > random_f64()
|
||||||
|
{
|
||||||
reflect(&unit_direction, &rec.normal)
|
reflect(&unit_direction, &rec.normal)
|
||||||
} else {
|
} else {
|
||||||
refract(&unit_direction, &rec.normal, refraction_ratio)
|
refract(&unit_direction, &rec.normal, refraction_ratio)
|
||||||
@@ -107,4 +133,4 @@ impl Material for Dielectric {
|
|||||||
*scattered = Ray::new(rec.p, direction);
|
*scattered = Ray::new(rec.p, direction);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,22 @@
|
|||||||
use rand::Rng;
|
use rand::RngExt;
|
||||||
|
|
||||||
// Constants
|
|
||||||
pub const INFINITY: f64 = std::f64::INFINITY;
|
|
||||||
pub const PI: f64 = std::f64::consts::PI;
|
|
||||||
|
|
||||||
// Utility Functions
|
// Utility Functions
|
||||||
pub fn degrees_to_radians(degrees: f64) -> f64 {
|
pub fn degrees_to_radians(degrees: f64) -> f64 {
|
||||||
degrees * std::f64::consts::PI / 180.0
|
degrees * std::f64::consts::PI / 180.0
|
||||||
}
|
}
|
||||||
|
|
||||||
// PLEASE CHANGE
|
|
||||||
pub fn random_f64() -> f64 {
|
pub fn random_f64() -> f64 {
|
||||||
rand::thread_rng().gen()
|
rand::rng().random()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PLEASE CHANGE
|
|
||||||
pub fn random_range_f64(min: f64, max: f64) -> f64 {
|
pub fn random_range_f64(min: f64, max: f64) -> f64 {
|
||||||
rand::thread_rng().gen_range(min, max)
|
rand::rng().random_range(min..max)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clamp(x: f64, min: f64, max: f64) -> f64 {
|
pub fn clamp(x: f64, min: f64, max: f64) -> f64 {
|
||||||
if x < min { return min; }
|
if x < min { return min; }
|
||||||
if x > max { return max; }
|
if x > max { return max; }
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: für jeden thread einen rng() erstellen und danach droppen, anstatt für jede execution rand::rng()
|
||||||
@@ -8,12 +8,12 @@ use crate::Ray;
|
|||||||
pub struct Sphere {
|
pub struct Sphere {
|
||||||
center: Point3,
|
center: Point3,
|
||||||
radius: f64,
|
radius: f64,
|
||||||
mat_ptr: Box<dyn Material>,
|
material: Box<dyn Material>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sphere {
|
impl Sphere {
|
||||||
pub fn new<T: Material + 'static>(center: Point3, radius: f64, mat_ptr: Box<T>) -> Self {
|
pub fn new<T: Material + 'static>(center: Point3, radius: f64, material: Box<T>) -> Self {
|
||||||
Sphere {center, radius, mat_ptr}
|
Sphere {center, radius, material}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ impl Hittable for Sphere {
|
|||||||
p: p,
|
p: p,
|
||||||
normal: outward_normal,
|
normal: outward_normal,
|
||||||
front_face,
|
front_face,
|
||||||
mat_ptr: self.mat_ptr.deref(),
|
material: self.material.deref(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user