aboutsummaryrefslogtreecommitdiff
path: root/src/camera/camera.rs
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2021-08-05 15:44:40 +0200
committerJulian T <julian@jtle.dk>2021-08-05 15:44:40 +0200
commit3ef8f4d918406eec6bdc29e0ebd883fabfac9b2e (patch)
treeaa4b1aac1e165821c16f222ebfb9212a9740e98b /src/camera/camera.rs
parent45119506c0293fdde6cef35f6e6f82d4055b46b6 (diff)
Add picture for c5505ab84820248c6dba35fc06aef9e0ced183derendered
Diffstat (limited to 'src/camera/camera.rs')
-rw-r--r--src/camera/camera.rs135
1 files changed, 0 insertions, 135 deletions
diff --git a/src/camera/camera.rs b/src/camera/camera.rs
deleted file mode 100644
index 7f9e79d..0000000
--- a/src/camera/camera.rs
+++ /dev/null
@@ -1,135 +0,0 @@
-//! Generates rays from screen coordinates
-//!
-//! Generates rays in world space from screen coordinates.
-//! Future versions should also simulate depth of field.
-//!
-//! # Examples
-//!
-//! ```
-//! use rendering::camera::{CameraSettings, Camera};
-//! use rendering::core::{Vector3f, Vector2f, Vector2i};
-//! use rendering::sample::UniformSampler;
-//!
-//! let set = CameraSettings {
-//! origin: Vector3f::new(10.0),
-//! target: Vector3f::new(0.0),
-//! up: Vector3f::new_xyz(0.0, 1.0, 0.0),
-//! fov: 90.0,
-//! filmsize: Vector2i::new(10),
-//! focus: None,
-//! aperture: None,
-//! };
-//!
-//! let cam = Camera::new(&set);
-//! let mut sampler = UniformSampler::new();
-//!
-//! let (r, _) = cam.generate_ray(&Vector2f::new(5.0), &mut sampler);
-//! let dir = r.direction;
-//!
-//! assert!(
-//! dir.x == -0.6031558065478413 &&
-//! dir.y == -0.6599739684616743 &&
-//! dir.z == -0.4479257014065748
-//! );
-//!
-//! ```
-use crate::Float;
-use crate::core::{Vector3f, Vector2f, Vector2i, Ray};
-use crate::sample::Sampler;
-
-/// A simple perspective camera
-pub struct Camera {
- /// The camera origin in the screen
- origin: Vector3f,
- /// Vector from camera origin to the screen lower left corner of the film plane
- screen_origin: Vector3f,
- /// Scaling vectors from screen_origin
- qx: Vector3f,
- qy: Vector3f,
-
- /// Value for depth of view
- lens_radius: Option<Float>,
-}
-
-/// Settings for initializing camera
-pub struct CameraSettings {
- /// Where rays originate from
- pub origin: Vector3f,
- /// Point where center of image is pointed at
- pub target: Vector3f,
- /// Vector that will be up in the resulting image
- pub up: Vector3f,
- /// The vertical field of view in degrees.
- /// Currently must be between [0; 180[.
- pub fov: Float,
- /// The film aspect ratio, height / width
- pub filmsize: Vector2i,
- /// The lens aperture
- ///
- /// Depth of view is disabled if None
- pub aperture: Option<Float>,
- /// The distance to the focus plane
- ///
- /// if None it will be set to the distance between origin and target
- pub focus: Option<Float>,
-}
-
-impl Camera {
- /// Create a new camera look at a target
- pub fn new(set: &CameraSettings) -> Camera {
- let filmsize = Vector2f::from(set.filmsize);
- // Calculate translation vectors
- let mut forward = set.target - set.origin;
-
- let focus = set.focus.unwrap_or_else(|| forward.length());
-
- forward.norm_in();
-
- let right = set.up.cross(&forward).norm();
- let newup = forward.cross(&right).norm();
-
- let aspect = (filmsize.y) / (filmsize.x);
- // Calculate screen size from fov and focus distance
- let width = 2.0 * focus * (set.fov / 2.0).to_radians().tan();
- let height = aspect * width;
-
- // Calculate screen scaling vectors
- let qx = right * (width / (filmsize.x - 1.0));
- let qy = newup * (height / (filmsize.y - 1.0));
-
- let screen_origin = forward * focus - (right * (width/2.0)) + (newup * (height/2.0));
-
- Camera {
- origin: set.origin,
- screen_origin,
- qx,
- qy,
- lens_radius: set.aperture.map(|a| a / 2.0),
- }
- }
-
- /// Generates a ray a screen space point
- ///
- /// The point coordinates should be between [0,1) with (0, 0) being the upper left corner
- ///
- /// Will return a ray and a weight
- ///
- /// The direction of the returned way is normalized
- pub fn generate_ray(&self, point: &Vector2f, sampler: &mut dyn Sampler) -> (Ray, Float) {
- // Depth of view origin offset
- let ooffset = match self.lens_radius {
- Some(r) => {
- let rand_dir = sampler.get_in_circle() * r;
- self.qx * rand_dir.x + self.qy * rand_dir.y
- },
- None => Vector3f::ZERO,
- };
-
- let dir = self.screen_origin + (self.qx * point.x) - (self.qy * point.y) - ooffset;
-
- (
- Ray { origin: self.origin + ooffset, direction: dir.norm() },
- 1.0
- )
- }
-}