added camera movement && a nice bokeh
This commit is contained in:
@@ -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 v = w.cross(&u);
|
||||||
|
|
||||||
let origin = Point3::new(0.0, 0.0, 0.0);
|
let origin = lookfrom;
|
||||||
let horizontal = Vec3::new(viewport_width, 0.0, 0.0);
|
let horizontal = focus_dist * viewport_width * u;
|
||||||
let vertical = Vec3::new(0.0, viewport_width, 0.0);
|
let vertical = focus_dist * viewport_height * v;
|
||||||
let lower_left_corner = origin - horizontal / 2.0 - vertical / 2.0 - Vec3::new(0.0, 0.0, focal_length);
|
let lower_left_corner = origin - horizontal/2.0 - vertical/2.0 - focus_dist * w;
|
||||||
|
|
||||||
Camera { origin, lower_left_corner, horizontal, vertical}
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
17
src/main.rs
17
src/main.rs
@@ -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();
|
||||||
|
|||||||
16
src/vec3.rs
16
src/vec3.rs
@@ -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()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,3 +248,13 @@ pub fn refract(uv: &Vec3, n: &Vec3, etai_over_etat: f64) -> Vec3 {
|
|||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user