diff options
author | Rosyid Haryadi <rosyid_haryadi@protonmail.com> | 2025-03-03 02:49:39 +0700 |
---|---|---|
committer | Rosyid Haryadi <rosyid_haryadi@protonmail.com> | 2025-03-03 02:49:39 +0700 |
commit | 8eec1dd60e966f068cd62fba87ca5dbc1aeb1978 (patch) | |
tree | 31f57a20fb600dd8fb3c328d65560d658ff38582 /src/camera.rs | |
parent | 988a418f8907fb5e3abb77222929d6ab7b60c1b6 (diff) |
upd camera field of view
Diffstat (limited to 'src/camera.rs')
-rw-r--r-- | src/camera.rs | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/src/camera.rs b/src/camera.rs index 1f211de..033f962 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,5 +1,5 @@ -use crate::calculus::calculus::{sample_square, Point3, Ray, Vec3}; -use crate::common::{get_image_height, Color, DisplayBuffer, Pixel, ASPECT_RATIO, CAMERA_CENTER, FOCAL_LENGTH, IMG_WIDTH, MAX_DEPTH, SAMPLES_PER_PIXEL, VIEWPORT_HEIGHT}; +use crate::calculus::calculus::{deg2rad, sample_square, Point3, Ray, Vec3}; +use crate::common::{get_image_height, Color, DisplayBuffer, Pixel, ASPECT_RATIO, CAMERA_CENTER, FOCAL_LENGTH, IMG_WIDTH, LOOK_AT, LOOK_FROM, MAX_DEPTH, SAMPLES_PER_PIXEL, VFOV, VIEWPORT_HEIGHT, VUP}; use crate::interval::Interval; use crate::material::{Material, MaterialType}; use crate::object::{HitRecord, Hittable, HittableList}; @@ -8,6 +8,10 @@ pub struct Camera { pub aspect_ratio: f32, pub image_width: usize, pub samples_per_pixel: usize, + pub vfov: f32, + pub look_from: Point3, + pub look_at: Point3, + pub vup: Vec3, image_height: usize, center: Point3, pixel_upper_left: Point3, @@ -17,30 +21,41 @@ pub struct Camera { max_depth: usize, } -impl Camera { - pub fn new() -> Self { +impl Default for Camera { + fn default() -> Self { let aspect_ratio = ASPECT_RATIO; let image_width = IMG_WIDTH; let image_height = get_image_height(image_width, aspect_ratio); - let center = CAMERA_CENTER; - let focal_length = FOCAL_LENGTH; + let vfov = VFOV; + let look_from = LOOK_FROM; + let look_at = LOOK_AT; + let vup = VUP; + + let center = look_from; + let focal_length = look_from.sub(&look_at).mag(); + let theta = deg2rad(vfov); + let h = (theta / 2.0).tan(); + + let w = look_from.sub(&look_at).unit(); + let u = vup.cross_prod(&w).unit(); + let v = w.cross_prod(&u).unit(); let samples_per_pixel = SAMPLES_PER_PIXEL; let pixel_samples_scale = 1.0 / samples_per_pixel as f32; - let viewport_height = VIEWPORT_HEIGHT; + let viewport_height = 2.0 * h * focal_length; let viewport_width = viewport_height * (image_width as f32 / image_height as f32); - let viewport_hor_vector = Vec3{ x: viewport_width, y: 0.0, z: 0.0 }; - let viewport_ver_vector = Vec3 { x: 0.0, y: -1f32 * viewport_height, z: 0.0 }; + let viewport_hor_vector = u.scalar_mul(viewport_height); + let viewport_ver_vector = v.scalar_mul(-1.0 * viewport_width); let delta_pixel_u = viewport_hor_vector.scalar_mul(1.0 / image_width as f32); let delta_pixel_v = viewport_ver_vector.scalar_mul(1.0 / image_height as f32); let viewport_upper_left = center - .sub(&Vec3 { x: 0f32, y: 0f32, z: focal_length}) + .sub(&w.scalar_mul(focal_length)) .sub(&viewport_hor_vector.scalar_mul(0.5)) .sub(&viewport_ver_vector.scalar_mul(0.5)); let pixel_upper_left = viewport_upper_left.add( @@ -59,10 +74,16 @@ impl Camera { delta_pixel_v, samples_per_pixel, pixel_samples_scale, - max_depth + max_depth, + vfov, + look_from, + look_at, + vup, } } +} +impl Camera { fn get_ray(&self, i: usize, j: usize) -> Ray { let offset = sample_square(); let pixel_sample = self.pixel_upper_left |