rust_pathtracer/camera/
pinhole.rs1
2use crate::prelude::*;
3
4pub struct Pinhole {
6 origin : F3,
7 center : F3,
8
9 fov : F,
10}
11
12impl Camera3D for Pinhole {
13
14 fn new() -> Self {
15
16 let origin = F3::new(0.0, 0.0, 3.0);
17 let center = F3::new(0.0, 0.0, 0.0);
18
19 Self {
20 origin,
21 center,
22
23 fov : 80.0,
24 }
25 }
26
27 fn set(&mut self, origin: F3, center: F3) {
28 self.origin = origin;
29 self.center = center;
30 }
31
32 fn set_fov(&mut self, fov: F) {
33 self.fov = fov;
34 }
35
36
37 #[inline(always)]
38 fn gen_ray(&self, p: F2, offset: F2, width: F, height: F) -> Ray {
39 let ratio = width / height;
40
41 let pixel_size = F2::new( 1.0 / width, 1.0 / height);
42
43 let half_width = (self.fov.to_radians() * 0.5).tan();
44 let half_height = half_width / ratio;
45
46 let up_vector = F3::new(0.0, 1.0, 0.0);
47
48 let w = (self.origin - self.center).normalize();
49 let u = (&up_vector).cross(&w);
50 let v = w.cross(&u);
51
52 let lower_left = self.origin - u.mult_f(&half_width) - v.mult_f(&half_height) - w;
53 let horizontal = u.mult_f(&(half_width * 2.0));
54 let vertical = v.mult_f(&(half_height * 2.0));
55
56 let mut rd = lower_left - self.origin;
57 rd += horizontal.mult_f(&(pixel_size.x * offset.x + p.x));
58 rd += vertical.mult_f(&(pixel_size.y * offset.y + p.y));
59
60 Ray::new(self.origin, rd.normalize())
61 }
62}