master
max.nuding 2022-07-06 08:48:00 +02:00
parent 28105145c4
commit 6f6fc5e375
Failed to extract signature
6 changed files with 70 additions and 56 deletions

View File

@ -19,22 +19,11 @@ impl Default for Aabb {
}
}
//impl Hittable for Aabb {
impl Aabb {
pub fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> bool {
let mut t_min = t_min;
let mut t_max = t_max;
for a in 0..3 {
/*
let t0 = ((self.minimum[a] - ray.origin()[a]) / ray.direction()[a])
.min((self.maximum[a] - ray.origin()[a]) / ray.direction()[a]);
let t1 = ((self.minimum[a] - ray.origin()[a]) / ray.direction()[a])
.max((self.maximum[a] - ray.origin()[a]) / ray.direction()[a]);
t_min = t0.min(t_min);
t_max = t1.max(t_max);
if t_max <= t_min {
return false;
}*/
let inv_d = 1.0 / ray.direction()[a];
let mut t0 = (self.minimum[a] - ray.origin()[a]) * inv_d;
let mut t1 = (self.maximum[a] - ray.origin()[a]) * inv_d;

View File

@ -1,4 +1,4 @@
use crate::hittable::{HittableList, Hittable, HitRecord};
use crate::hittable::{HittableList, Hittable, HitRecord, HittableObject};
use crate::aabb::Aabb;
use std::cmp;
use crate::Ray;
@ -7,7 +7,7 @@ use crate::Ray;
enum BVHNode {
Branch { left: Box<BVH>, right: Box<BVH> },
Leaf(Box<dyn Hittable>)
Leaf(HittableObject)
}
pub struct BVH {
@ -17,7 +17,7 @@ pub struct BVH {
impl BVH {
pub fn new(mut objects: HittableList, time0: f64, time1: f64) -> Self {
fn box_compare(time0: f64, time1: f64, axis: usize) -> impl FnMut(&Box<dyn Hittable + Sync>, &Box<dyn Hittable + Sync>) -> cmp::Ordering {
fn box_compare(time0: f64, time1: f64, axis: usize) -> impl FnMut(&HittableObject, &HittableObject) -> cmp::Ordering {
move |a, b| {
let a_bbox = a.bounding_box(time0, time1);
let b_bbox = b.bounding_box(time0, time1);
@ -90,7 +90,7 @@ impl Hittable for BVH {
}
}
}
fn bounding_box(&self, time0: f64, time1: f64) -> Option<Aabb> {
fn bounding_box(&self, _time0: f64, _time1: f64) -> Option<Aabb> {
Some(self.bounding_box)
}
}

View File

@ -2,8 +2,10 @@ use crate::{Point3, Ray, Vec3};
use crate::material::{Material};
use crate::aabb::Aabb;
use std::f64::consts::PI;
use std::sync::Arc;
pub type HittableList = Vec<Box<dyn Hittable + Sync>>;
pub type HittableObject = Arc<dyn Hittable + Sync + Send>;
pub type HittableList = Vec<HittableObject>;
//#[derive(Debug, Clone, Copy)]
#[derive(Clone, Copy)]
@ -14,7 +16,7 @@ pub struct HitRecord<'material> {
pub u: f64,
pub v: f64,
pub front_face: bool,
pub material: &'material Material
pub material: &'material Arc<Material>
}
pub trait Hittable {
@ -26,10 +28,10 @@ pub trait Hittable {
pub struct Sphere {
pub center: Point3,
pub radius: f64,
pub material: Material
pub material: Arc<Material>
}
impl Sphere {
pub fn new(center: Point3, radius: f64, material: Material) -> Sphere {
pub fn new(center: Point3, radius: f64, material: Arc<Material>) -> Sphere {
Sphere { center, radius, material }
}
pub fn uv(point: &Point3) -> (f64, f64) {
@ -51,7 +53,7 @@ impl Default for Sphere {
Sphere {
center: Point3::default(),
radius: 0.0,
material: Material::default()
material: Arc::new(Material::default())
}
}
}
@ -100,7 +102,7 @@ pub struct MovableSphere {
pub center0: Point3,
pub center1: Point3,
pub radius: f64,
pub material: Material,
pub material: Arc<Material>,
pub time0: f64,
pub time1: f64,
}
@ -109,7 +111,7 @@ impl MovableSphere {
center0: Point3,
center1: Point3,
radius: f64,
material: Material,
material: Arc<Material>,
time0: f64,
time1: f64) -> Self {
MovableSphere { center0, center1, radius, material, time0, time1 }
@ -124,7 +126,7 @@ impl Default for MovableSphere {
center0: Point3::default(),
center1: Point3::default(),
radius: 0.0,
material: Material::default(),
material: Arc::new(Material::default()),
time0: 0.0,
time1: 0.0
}

View File

@ -1,8 +1,8 @@
use std::sync::Mutex;
use std::sync::{Arc, Mutex};
use std::time::Instant;
use crate::camera::Camera;
use crate::hittable::{Hittable, Sphere, HittableList};
use crate::hittable::{Hittable, Sphere, HittableList, HittableObject};
use crate::output::{Output, PNG};
use crate::ray::Ray;
use crate::vec3::{Color, Point3, Vec3};
@ -25,20 +25,38 @@ mod aabb;
mod bvh;
mod texture;
fn random_scene() -> HittableList {
fn two_spheres() -> HittableList {
let mut world:HittableList = Vec::new();
//let material_ground = Material::Lambertian(Lambertian::new(Color::new(0.5, 0.5, 0.5)));
let checker = CheckerTexture::colored(
Color::new(0.2, 0.3, 0.1),
Color::new(0.9, 0.9, 0.9));
let material_ground = Material::Lambertian(Lambertian::textured(Box::new(checker)));
let checker_material = Arc::new(Material::Lambertian(Lambertian::textured(Arc::new(checker))));
world.push(Arc::new(Sphere {
center: Point3::new(0.0, -10.0, 0.0),
radius: 10.0,
material: Arc::clone(&checker_material)
}));
world.push(Arc::new(Sphere {
center: Point3::new(0.0, 10.0, 0.0),
radius: 10.0,
material: checker_material
}));
world
}
fn random_scene() -> HittableList {
let mut world: HittableList = Vec::new();
let checker = CheckerTexture::colored(
Color::new(0.2, 0.3, 0.1),
Color::new(0.9, 0.9, 0.9));
let material_ground = Arc::new(Material::Lambertian(Lambertian::textured(Arc::new(checker))));
let ground = Sphere {
center: Point3::new(0.0, -1000.0, 0.0),
radius: 1000.0,
material: material_ground
};
world.push(Box::new(ground));
world.push(Arc::new(ground));
let unit_range = Uniform::from(0.0..1.0);
let fuzz_range = Uniform::from(0.0..0.5);
@ -55,17 +73,17 @@ fn random_scene() -> HittableList {
continue;
}
let material = match choose_material {
_ if choose_material < 0.8 => Material::Lambertian(Lambertian::new(
Color::random(0.0, 1.0) * Color::random(0.0, 1.0))),
_ if choose_material < 0.95 => Material::Metal(Metal::new(
_ if choose_material < 0.8 => Arc::new(Material::Lambertian(Lambertian::new(
Color::random(0.0, 1.0) * Color::random(0.0, 1.0)))),
_ if choose_material < 0.95 => Arc::new(Material::Metal(Metal::new(
Color::random(0.5, 1.0),
fuzz_range.sample(&mut rng))),
_ => Material::Dielectric(Dielectric::new(1.5)),
fuzz_range.sample(&mut rng)))),
_ => Arc::new(Material::Dielectric(Dielectric::new(1.5))),
};
let sphere: Box<dyn Hittable + Sync> = match rng.gen_bool(1.0 / 3.0) {
let sphere: HittableObject = match rng.gen_bool(1.0 / 3.0) {
true => {
let center1 = center + Vec3::new(0.0, fuzz_range.sample(&mut rng) / 2.0, 0.0);
Box::new(MovableSphere {
Arc::new(MovableSphere {
center0: center,
center1,
radius: 0.2,
@ -74,7 +92,7 @@ fn random_scene() -> HittableList {
time1: 1.0
})
}
false => Box::new(Sphere {
false => Arc::new(Sphere {
center,
radius: 0.2,
material
@ -84,20 +102,20 @@ fn random_scene() -> HittableList {
}
}
let material1 = Material::Dielectric(Dielectric::new(1.5));
world.push(Box::new(Sphere {
let material1 = Arc::new(Material::Dielectric(Dielectric::new(1.5)));
world.push(Arc::new(Sphere {
center: Point3::new(0.0, 1.0, 0.0),
radius: 1.0,
material: material1
}));
let material2 = Material::Lambertian(Lambertian::new(Color::new(0.4, 0.2, 0.1)));
world.push(Box::new(Sphere {
let material2 = Arc::new(Material::Lambertian(Lambertian::new(Color::new(0.4, 0.2, 0.1))));
world.push(Arc::new(Sphere {
center: Point3::new(-4.0, 1.0, 0.0),
radius: 1.0,
material: material2
}));
let material3 = Material::Metal(Metal::new(Color::new(0.7, 0.6, 0.5), 0.0));
world.push(Box::new(Sphere {
let material3 = Arc::new(Material::Metal(Metal::new(Color::new(0.7, 0.6, 0.5), 0.0)));
world.push(Arc::new(Sphere {
center: Point3::new(4.0, 1.0, 0.0),
radius: 1.0,
material: material3
@ -117,20 +135,25 @@ fn main() {
let look_from = Point3::new(13.0, 2.0, 3.0);
let look_at = Point3::new(0.0, 0.0, 0.0);
let focus_dist = 10.0;
// Camera
let cam = Camera::new(
look_from,
look_at,
Vec3::new(0.0, 1.0, 0.0),
ASPECT_RATIO,
20.0,
0.1,
40.0,
0.0,
focus_dist,
0.0,
1.0);
// World
let world= random_scene();
let scene: u8 = 0;
let world = match scene {
0 => two_spheres(),
_ => random_scene()
};
let between = Uniform::from(0.0..1.0);

View File

@ -1,3 +1,5 @@
use std::rc::Rc;
use std::sync::Arc;
use rand::Rng;
use crate::hittable::HitRecord;
use crate::{Color, Ray, Vec3};
@ -7,7 +9,6 @@ pub trait Scatterable {
fn scatter(&self, ray: &Ray, hit_record: &HitRecord) -> Option<(Option<Ray>, Color)>;
}
//#[derive(Debug, Clone)]
pub enum Material {
Lambertian(Lambertian),
Metal(Metal),
@ -30,16 +31,15 @@ impl Scatterable for Material {
}
}
//#[derive(Debug, Clone)]
pub struct Lambertian {
pub albedo: Box<dyn Texture>
pub albedo: Arc<dyn Texture>
}
impl Lambertian {
pub fn new(albedo: Color) -> Self {
let texture = SolidColor::from(albedo);
Lambertian { albedo: Box::new(texture) }
Lambertian { albedo: Arc::new(texture) }
}
pub fn textured(albedo: Box<dyn Texture>) -> Self {
pub fn textured(albedo: Arc<dyn Texture>) -> Self {
Lambertian { albedo }
}
}

View File

@ -1,6 +1,6 @@
use crate::{Point3, Color};
pub trait Texture: Sync {
pub trait Texture: Sync + Send {
fn value(&self, u: f64, v: f64, point: &Point3) -> Color;
}
@ -45,9 +45,9 @@ impl CheckerTexture {
impl Texture for CheckerTexture {
fn value(&self, u: f64, v: f64, point: &Point3) -> Color {
let sines = (10.0 * point.x().sin()) *
(10.0 * point.y().sin()) *
(10.0 * point.z().sin());
let sines = (10.0 * point.x()).sin() *
(10.0 * point.y()).sin() *
(10.0 * point.z()).sin();
match sines {
sines if sines < 0.0 => self.odd.value(u, v, point),
_ => self.even.value(u, v, point),