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,
horizontal: Vec3,
vertical: Vec3,
u: Vec3,
v: Vec3,
w: Vec3,
lens_radius: f64,
}
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 h = f64::tan(theta/2.0);
let viewport_height = 2.0 * h;
let viewport_width = aspect_ratio * viewport_height;
let focal_length = 1.0;
let origin = Point3::new(0.0, 0.0, 0.0);
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);
let w = (lookfrom - lookat).unit_vector();
let u = (vup.cross(&w)).unit_vector();
let v = w.cross(&u);
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 {
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_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.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, 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)));
// 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
//let mut rng = rand::thread_rng();

View File

@@ -45,9 +45,9 @@ impl Vec3 {
pub fn cross(&self, rhs: &Self) -> Self {
Self {
elements: [
self.y() * rhs.z() + self.z() * rhs.y(),
self.z() * rhs.x() + self.x() * rhs.z(),
self.x() * rhs.y() + self.y() * rhs.x()
self.y() * rhs.z() - self.z() * rhs.y(),
self.z() * rhs.x() - self.x() * rhs.z(),
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;
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;
}
}