Add XY aligned rects

This commit is contained in:
max.nuding 2022-07-08 08:13:42 +02:00
parent 11c4d2c991
commit 14b5b2b125
Failed to extract signature
2 changed files with 103 additions and 1 deletions

View File

@ -15,6 +15,7 @@ use crate::image_texture::ImageTexture;
use crate::noise::NoiseTexture; use crate::noise::NoiseTexture;
use crate::perlin::Perlin; use crate::perlin::Perlin;
use crate::texture::CheckerTexture; use crate::texture::CheckerTexture;
use crate::xy_rect::XyRect;
mod vec3; mod vec3;
mod ray; mod ray;
@ -28,6 +29,7 @@ mod texture;
mod perlin; mod perlin;
mod noise; mod noise;
mod image_texture; mod image_texture;
mod xy_rect;
// Image // Image
const ASPECT_RATIO: f64 = 3.0 / 2.0; const ASPECT_RATIO: f64 = 3.0 / 2.0;
@ -42,6 +44,57 @@ struct Scene {
pub background: Color pub background: Color
} }
fn simple_light() -> Scene {
let mut world:HittableList = Vec::new();
let noise = NoiseTexture { noise: Perlin::new(), scale: 4.0 };
let noise_material = Arc::new(Material::Lambertian(Lambertian::textured(Arc::new(noise))));
world.push(Arc::new(Sphere {
center: Point3::new(0.0, -1000.0, 0.0),
radius: 1000.0,
material: Arc::clone(&noise_material)
}));
world.push(Arc::new(Sphere {
center: Point3::new(0.0, 2.0, 0.0),
radius: 2.0,
material: noise_material
}));
let difflight = Material::DiffuseLight(
// Brighter than 1.0/1.0/1.0 so it can light things
DiffuseLight::from(Color::new(4.0, 4.0, 4.0)));
world.push(Arc::new(XyRect {
x0: 3.0,
x1: 5.0,
y0: 1.0,
y1: 3.0,
k: -2.0,
material: Arc::new(difflight)
}));
let look_from = Point3::new(26.0, 3.0, 6.0);
let look_at = Point3::new(0.0, 2.0, 0.0);
let focus_dist = 2.0;
let cam = Camera::new(
look_from,
look_at,
Vec3::new(0.0, 1.0, 0.0),
ASPECT_RATIO,
20.0,
0.0,
focus_dist,
0.0,
1.0);
Scene {
world,
cam,
background: Color::default()
}
}
fn sun() -> Scene { fn sun() -> Scene {
let mut world:HittableList = Vec::new(); let mut world:HittableList = Vec::new();
let earth_material = Arc::new( let earth_material = Arc::new(
@ -283,12 +336,13 @@ fn random_scene() -> Scene {
fn main() { fn main() {
// World // World
let scene: u8 = 3; let scene: u8 = 4;
let scene_setup = match scene { let scene_setup = match scene {
0 => two_spheres(), 0 => two_spheres(),
1 => two_perlin_spheres(), 1 => two_perlin_spheres(),
2 => earth(), 2 => earth(),
3 => sun(), 3 => sun(),
4 => simple_light(),
_ => random_scene(), _ => random_scene(),
}; };

48
src/xy_rect.rs Normal file
View File

@ -0,0 +1,48 @@
use std::sync::Arc;
use crate::hittable::{HitRecord, Hittable};
use crate::{Aabb, Material, Point3, Ray, Vec3};
pub struct XyRect {
pub x0: f64,
pub x1: f64,
pub y0: f64,
pub y1: f64,
pub k: f64,
pub material: Arc<Material>
}
impl Hittable for XyRect {
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
let t = (self.k - ray.origin().z()) / ray.direction().z();
if t < t_min || t > t_max {
return None;
}
let x = ray.origin().x() + t * ray.direction().x();
let y = ray.origin().y() + t * ray.direction().y();
if x < self.x0 || x > self.x1 || y < self.y0 || y > self.y1 {
return None;
}
let normal = Vec3::new(0.0, 0.0, 1.0);
let dot = ray.direction().dot(&normal);
let front_face = dot < 0.0;
let normal = if front_face { normal } else { -normal };
Some(HitRecord {
point: ray.at(t),
normal,
t,
u: (x-self.x0)/(self.x1-self.x0),
v: (y-self.y0)/(self.y1-self.y0),
front_face,
material: &self.material
})
}
fn bounding_box(&self, _time0: f64, _time1: f64) -> Option<Aabb> {
// The bounding box must have non-zero width in each dimension, so pad the Z
// dimension a small amount.
Some(Aabb {
minimum: Point3::new(self.x0, self.y0, self.k-0.0001),
maximum: Point3::new(self.x1, self.y1, self.k+0.0001),
})
}
}