added camera movement && a nice bokeh
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
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_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();
|
||||
|
||||
16
src/vec3.rs
16
src/vec3.rs
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user