added camera movement && a nice bokeh

This commit is contained in:
2023-02-03 00:31:34 +01:00
parent a28e2e98d1
commit b9ab4d6557
4 changed files with 57 additions and 15 deletions

BIN
img.ppm

Binary file not shown.

View File

@@ -7,29 +7,48 @@ pub struct Camera {
lower_left_corner: Point3, lower_left_corner: Point3,
horizontal: Vec3, horizontal: Vec3,
vertical: Vec3, vertical: Vec3,
u: Vec3,
v: Vec3,
w: Vec3,
lens_radius: f64,
} }
impl Camera { impl Camera {
pub fn new(vfov: f64, aspect_ratio: f64) -> Self { pub fn new(
lookfrom: Point3,
lookat: Point3,
vup: Vec3,
vfov: f64,
aspect_ratio: f64,
apeture: f64,
focus_dist: f64,
) -> Self {
let theta = degrees_to_radians(vfov); let theta = degrees_to_radians(vfov);
let h = f64::tan(theta/2.0); 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;
let focal_length = 1.0; let w = (lookfrom - lookat).unit_vector();
let u = (vup.cross(&w)).unit_vector();
let origin = Point3::new(0.0, 0.0, 0.0); let v = w.cross(&u);
let horizontal = Vec3::new(viewport_width, 0.0, 0.0);
let vertical = Vec3::new(0.0, viewport_width, 0.0);
let lower_left_corner = origin - horizontal / 2.0 - vertical / 2.0 - Vec3::new(0.0, 0.0, focal_length);
Camera { origin, lower_left_corner, horizontal, vertical} let origin = lookfrom;
let horizontal = focus_dist * viewport_width * u;
let vertical = focus_dist * viewport_height * v;
let lower_left_corner = origin - horizontal/2.0 - vertical/2.0 - focus_dist * w;
let lens_radius = apeture / 2.0;
Camera { origin, lower_left_corner, horizontal, vertical, u, v, w, lens_radius}
} }
pub fn get_ray(&self, u: f64, v: f64) -> Ray { pub fn get_ray(&self, s: f64, t: f64) -> Ray {
let rd = self.lens_radius * random_in_unit_disk();
let offset = self.u * rd.x() + self.v * rd.y();
Ray { Ray {
origin: self.origin, origin: self.origin,
direction: self.lower_left_corner + u * self.horizontal + v * self.vertical - self.origin direction: self.lower_left_corner + s*self.horizontal + t*self.vertical - self.origin - offset
} }
} }
} }

View File

@@ -58,7 +58,7 @@ fn main() {
static MATERIAL_GROUND: Lambertian = Lambertian::new(Color::new(0.3, 0.8, 0.0)); 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_CENTER: Lambertian = Lambertian::new(Color::new(0.1, 0.2, 0.5));
static MATERIAL_LEFT: Dielectric = Dielectric::new(1.5); static MATERIAL_LEFT: Dielectric = Dielectric::new(1.5);
static MATERIAL_RIGHT: Metal = Metal::new(Color::new(0.8, 0.6, 0.2), 0.3); static MATERIAL_RIGHT: Metal = Metal::new(Color::new(0.8, 0.6, 0.2), 0.0);
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, -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(0.0, 0.0, -1.0), 0.5, &MATERIAL_CENTER)));
@@ -66,7 +66,20 @@ fn main() {
world.add(Box::new(Sphere::new(Point3::new(1.0, 0.0, -1.0), 0.5, &MATERIAL_RIGHT))); world.add(Box::new(Sphere::new(Point3::new(1.0, 0.0, -1.0), 0.5, &MATERIAL_RIGHT)));
// Camera // Camera
let cam = Camera::new(90.0, aspect_ratio); 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 = (lookfrom-lookat).length_squared();
let cam = Camera::new(
lookfrom,
lookat,
vup,
30.0,
aspect_ratio,
0.0,
dist_to_focus
);
// Render // Render
//let mut rng = rand::thread_rng(); //let mut rng = rand::thread_rng();

View File

@@ -45,9 +45,9 @@ impl Vec3 {
pub fn cross(&self, rhs: &Self) -> Self { pub fn cross(&self, rhs: &Self) -> Self {
Self { Self {
elements: [ elements: [
self.y() * rhs.z() + self.z() * rhs.y(), self.y() * rhs.z() - self.z() * rhs.y(),
self.z() * rhs.x() + self.x() * rhs.z(), self.z() * rhs.x() - self.x() * rhs.z(),
self.x() * rhs.y() + self.y() * rhs.x() self.x() * rhs.y() - self.y() * rhs.x()
] ]
} }
} }
@@ -247,4 +247,14 @@ pub fn refract(uv: &Vec3, n: &Vec3, etai_over_etat: f64) -> Vec3 {
let r_out_parallel = -f64::sqrt(f64::abs(1.0 - r_out_perp.length_squared())) * *n; let r_out_parallel = -f64::sqrt(f64::abs(1.0 - r_out_perp.length_squared())) * *n;
r_out_perp + r_out_parallel r_out_perp + r_out_parallel
}
pub fn random_in_unit_disk() -> Vec3 {
loop {
let p = Vec3::new(random_range_f64(-1.0, 1.0), random_range_f64(-1.0, 1.0), 0.0);
if p.length_squared() >= 1.0 {
continue;
}
return p;
}
} }