library: core: camera: move film behind the camera
To prepare for adding the handling of focal blur, move the film so that it is behind the point of convergence of the lens. In addition, store the distance to the focal plane in the camera, which will be used when calculating rays with an non-zero aperture.
This commit is contained in:
parent
2f3224ea07
commit
9ad1100ded
|
@ -12,6 +12,8 @@ use serde::Deserialize;
|
||||||
pub struct Camera {
|
pub struct Camera {
|
||||||
/// Where the camera is set in the scene (i.e: its focal point).
|
/// Where the camera is set in the scene (i.e: its focal point).
|
||||||
origin: Point,
|
origin: Point,
|
||||||
|
/// How far away is the camera's plan of focus.
|
||||||
|
distance_to_image: f32,
|
||||||
/// The film to represent each pixel in the scene.
|
/// The film to represent each pixel in the scene.
|
||||||
film: Film,
|
film: Film,
|
||||||
}
|
}
|
||||||
|
@ -40,15 +42,20 @@ impl Camera {
|
||||||
forward: Vector,
|
forward: Vector,
|
||||||
up: Vector,
|
up: Vector,
|
||||||
fov: f32,
|
fov: f32,
|
||||||
dist_to_image: f32,
|
distance_to_image: f32,
|
||||||
x: u32,
|
x: u32,
|
||||||
y: u32,
|
y: u32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let right = forward.cross(&up);
|
let right = forward.cross(&up);
|
||||||
let center = origin + forward.normalize() * dist_to_image;
|
let screen_size = 2. * f32::tan(fov / 2.);
|
||||||
let screen_size = 2. * f32::tan(fov / 2.) * dist_to_image;
|
// Construct the film behind the camera, upside down
|
||||||
let film = Film::new(x, y, screen_size, center, up, right);
|
let center = origin - forward.normalize();
|
||||||
Camera { origin, film }
|
let film = Film::new(x, y, screen_size, center, -up, -right);
|
||||||
|
Camera {
|
||||||
|
origin,
|
||||||
|
distance_to_image,
|
||||||
|
film,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `Camera`'s [`Film`].
|
/// Get the `Camera`'s [`Film`].
|
||||||
|
@ -96,7 +103,7 @@ impl Camera {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn ray_with_ratio(&self, x: f32, y: f32) -> Ray {
|
pub fn ray_with_ratio(&self, x: f32, y: f32) -> Ray {
|
||||||
let pixel = self.film().pixel_at_ratio(x, y);
|
let pixel = self.film().pixel_at_ratio(x, y);
|
||||||
let direction = Unit::new_normalize(pixel - self.origin());
|
let direction = Unit::new_normalize(self.origin() - pixel);
|
||||||
Ray::new(pixel, direction)
|
Ray::new(pixel, direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +175,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn new_works() {
|
fn new_works() {
|
||||||
let cam = Camera::new(
|
let cam = Camera::new(
|
||||||
Point::new(-1., 0., 0.),
|
Point::new(1., 0., 0.),
|
||||||
Vector::new(1., 0., 0.),
|
Vector::new(1., 0., 0.),
|
||||||
Vector::new(0., 1., 0.),
|
Vector::new(0., 1., 0.),
|
||||||
2. * f32::atan(1.), /* 90° in radian */
|
2. * f32::atan(1.), /* 90° in radian */
|
||||||
|
@ -179,14 +186,15 @@ mod test {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cam,
|
cam,
|
||||||
Camera {
|
Camera {
|
||||||
origin: Point::new(-1., 0., 0.),
|
origin: Point::new(1., 0., 0.),
|
||||||
|
distance_to_image: 1.,
|
||||||
film: Film::new(
|
film: Film::new(
|
||||||
1080,
|
1080,
|
||||||
1080,
|
1080,
|
||||||
2.,
|
2.,
|
||||||
Point::origin(),
|
Point::origin(),
|
||||||
Vector::new(0., 1., 0.),
|
-Vector::new(0., 1., 0.),
|
||||||
Vector::new(0., 0., 1.),
|
-Vector::new(0., 0., 1.),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -195,7 +203,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialization_works() {
|
fn deserialization_works() {
|
||||||
let yaml = r#"
|
let yaml = r#"
|
||||||
origin: [-1.0, 0.0, 0.0]
|
origin: [1.0, 0.0, 0.0]
|
||||||
forward: [ 1.0, 0.0, 0.0]
|
forward: [ 1.0, 0.0, 0.0]
|
||||||
up: [0.0, 1.0, 0.0]
|
up: [0.0, 1.0, 0.0]
|
||||||
fov: 90.0
|
fov: 90.0
|
||||||
|
@ -207,14 +215,15 @@ mod test {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cam,
|
cam,
|
||||||
Camera {
|
Camera {
|
||||||
origin: Point::new(-1., 0., 0.),
|
origin: Point::new(1., 0., 0.),
|
||||||
|
distance_to_image: 1.0,
|
||||||
film: Film::new(
|
film: Film::new(
|
||||||
1080,
|
1080,
|
||||||
1080,
|
1080,
|
||||||
2.,
|
2.,
|
||||||
Point::origin(),
|
Point::origin(),
|
||||||
Vector::new(0., 1., 0.),
|
-Vector::new(0., 1., 0.),
|
||||||
Vector::new(0., 0., 1.),
|
-Vector::new(0., 0., 1.),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue