latest
This commit is contained in:
16
src/main.rs
16
src/main.rs
@@ -23,18 +23,18 @@ use crate::{
|
||||
camera::*, material::{Lambertian, Dielectric},
|
||||
};
|
||||
|
||||
fn ray_color(r: &Ray, world: &mut dyn Hittable, depth: i32) -> Color {
|
||||
fn ray_color(r: Ray, world: &mut 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, INFINITY) {
|
||||
if let Some(rec) = world.hit(&r, 0.001, INFINITY) {
|
||||
let mut scattered = Ray::new_empty();
|
||||
let mut attenuation = Color::new_empty();
|
||||
|
||||
if rec.mat_ptr.scatter(r, rec, &mut attenuation, &mut scattered) {
|
||||
return attenuation * ray_color(&scattered, world, depth - 1);
|
||||
return attenuation * ray_color(scattered, world, depth - 1);
|
||||
}
|
||||
return Color::new_empty();
|
||||
}
|
||||
@@ -50,7 +50,7 @@ fn main() {
|
||||
let aspect_ratio: f64 = 1.0 / 1.0;
|
||||
let image_width: i32 = 512;
|
||||
let image_height: i32 = (image_width as f64 / aspect_ratio as f64) as i32;
|
||||
let samples_per_pixel: i32 = 100;
|
||||
let samples_per_pixel: i32 = 200;
|
||||
let max_depth: i32 = 4;
|
||||
|
||||
// World
|
||||
@@ -58,15 +58,15 @@ fn main() {
|
||||
static MATERIAL_GROUND: Lambertian = Lambertian::new(Color::new(0.3, 0.8, 0.0));
|
||||
static MATERIAL_CENTER: Lambertian = Lambertian::new(Color::new(0.1, 0.2, 0.5));
|
||||
static MATERIAL_LEFT: Dielectric = Dielectric::new(1.5);
|
||||
static MATERIAL_RIGHT: Metal = Metal::new(Color::new(0.8, 0.6, 0.2), 0.0);
|
||||
static MATERIAL_RIGHT: Metal = Metal::new(Color::new(0.8, 0.6, 0.2), 0.3);
|
||||
|
||||
world.add(Box::new(Sphere::new(Point3::new(0.0, -100.5, -1.0), 100.0, &MATERIAL_GROUND)));
|
||||
world.add(Box::new(Sphere::new(Point3::new(0.0, 0.0, -1.0), 0.5, &MATERIAL_CENTER)));
|
||||
world.add(Box::new(Sphere::new(Point3::new(-1.0, 0.0, -1.0), -0.5, &MATERIAL_LEFT)));
|
||||
world.add(Box::new(Sphere::new(Point3::new(-1.0, 0.0, -1.0), 0.5, &MATERIAL_LEFT)));
|
||||
world.add(Box::new(Sphere::new(Point3::new(1.0, 0.0, -1.0), 0.5, &MATERIAL_RIGHT)));
|
||||
|
||||
// Camera
|
||||
let cam = Camera::new(120.0, aspect_ratio);
|
||||
let cam = Camera::new(90.0, aspect_ratio);
|
||||
|
||||
// Render
|
||||
//let mut rng = rand::thread_rng();
|
||||
@@ -83,7 +83,7 @@ fn main() {
|
||||
let u = (i as f64 + random_f64()) / (image_width - 1) as f64;
|
||||
let v = (j as f64 + random_f64()) / (image_height - 1) as f64;
|
||||
let r: Ray = cam.get_ray(u, v);
|
||||
pixel_color += ray_color(&r, &mut world, max_depth)
|
||||
pixel_color += ray_color(r, &mut world, max_depth)
|
||||
}
|
||||
write_color_bin(&mut file, pixel_color, samples_per_pixel);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,21 @@ use crate::ray::Ray;
|
||||
use crate::rtweekend::random_f64;
|
||||
use crate::vec3::{Color, random_unit_vector, reflect, refract};
|
||||
|
||||
pub trait Material: {
|
||||
fn scatter(&self, r_in: &Ray, rec: HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool;
|
||||
//More rusty
|
||||
/*
|
||||
pub struct ScatterData {
|
||||
attenuation: Color,
|
||||
scattered: Ray
|
||||
}
|
||||
|
||||
pub trait Material {
|
||||
fn scatter(&self, r_in: Ray, rec: HitRecord) -> Option<ScatterData>;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
pub trait Material {
|
||||
fn scatter(&self, r_in: Ray, rec: HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool;
|
||||
}
|
||||
|
||||
pub struct Lambertian {
|
||||
@@ -18,7 +31,7 @@ impl 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();
|
||||
|
||||
if scatter_direction.near_zero() {
|
||||
@@ -43,7 +56,7 @@ impl Metal {
|
||||
}
|
||||
|
||||
impl Material for Metal {
|
||||
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 reflected = reflect(&r_in.direction(), &rec.normal);
|
||||
*scattered = Ray::new(rec.p, reflected + self.fuzz*random_unit_vector());
|
||||
*attenuation = self.albedo;
|
||||
@@ -65,13 +78,13 @@ impl Dielectric {
|
||||
// Schlick
|
||||
let mut r0 = (1.0-ref_idx) / (1.0+ref_idx);
|
||||
r0 = r0*r0;
|
||||
|
||||
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 {
|
||||
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);
|
||||
let refraction_ratio: f64 = if rec.front_face {
|
||||
1.0/self.ir
|
||||
@@ -83,7 +96,7 @@ impl Material for Dielectric {
|
||||
let cos_theta = f64::min(-unit_direction.dot(&rec.normal), 1.0);
|
||||
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() {
|
||||
reflect(&unit_direction, &rec.normal)
|
||||
|
||||
Reference in New Issue
Block a user