12.2.Positioning and Orienting the Camera

This commit is contained in:
dengqn 2025-08-14 19:16:08 +08:00
parent 5c1c9a3edd
commit caa21505ba
3 changed files with 26 additions and 13 deletions

View File

@ -14,13 +14,15 @@ impl<'a> Camera<'a> {
fov: f32, fov: f32,
image_width: i32, image_width: i32,
aspect_ratio: f32, aspect_ratio: f32,
camera_center: Point, center: Point,
focal_length: f32, look_at: Point,
v_up: Vec3,
sample_times: i8, sample_times: i8,
reflect_depth: i8, reflect_depth: i8,
ppm_file_writer: &'a mut PPMWriter<BufWriter<File>> ppm_file_writer: &'a mut PPMWriter<BufWriter<File>>
) -> Self { ) -> Self {
let focal_length = (look_at - center).length();
let theta = degrees_to_radians(fov); let theta = degrees_to_radians(fov);
let h = f32::tan(theta / 2.); let h = f32::tan(theta / 2.);
@ -29,18 +31,24 @@ impl<'a> Camera<'a> {
let image_height = ((image_width as f32 / aspect_ratio) as i32).max(1); let image_height = ((image_width as f32 / aspect_ratio) as i32).max(1);
let viewport_width = viewport_height * (image_width as f32 / image_height as f32); let viewport_width = viewport_height * (image_width as f32 / image_height as f32);
let viewport_u = Vec3::new(viewport_width, 0.0, 0.0);
let w = (center - look_at).normalize();
let u = v_up.cross(w).normalize();
let v = w.cross(u);
let viewport_u = viewport_width * u;
// image x--> right // image x--> right
// | // |
// y // y
// space: y up , x right , z back, -z front // space: y up , x right , z back, -z front
let viewport_v = Vec3::new(0.0, -viewport_height, 0.0); let viewport_v = viewport_height * (-1. * v);
// width per pix // width per pix
let viewport_u_delta = viewport_u / (image_width as f32); let viewport_u_delta = viewport_u / (image_width as f32);
// height per pix // height per pix
let viewport_v_delta = viewport_v / (image_height as f32); let viewport_v_delta = viewport_v / (image_height as f32);
let viewport_top_left_pixel = let viewport_top_left_pixel =
camera_center - Vec3::new(0., 0., focal_length) - viewport_u / 2.0 - viewport_v / 2.0; center - focal_length * w - viewport_u / 2.0 - viewport_v / 2.0;
// padding 0.5* delta u/v // padding 0.5* delta u/v
let viewport_top_left_pixel_center = let viewport_top_left_pixel_center =
viewport_top_left_pixel - viewport_u_delta / 2.0 - viewport_v_delta / 2.0; viewport_top_left_pixel - viewport_u_delta / 2.0 - viewport_v_delta / 2.0;
@ -51,7 +59,9 @@ impl<'a> Camera<'a> {
// aspect_ratio, // aspect_ratio,
// viewport_width, // viewport_width,
// viewport_height, // viewport_height,
camera_center, center,
look_at,
v_up,
// focal_length, // focal_length,
// viewport_u, // viewport_u,
// viewport_v, // viewport_v,
@ -81,7 +91,7 @@ impl<'a> Camera<'a> {
let pix_sample = self.viewport_top_left_pixel_center let pix_sample = self.viewport_top_left_pixel_center
+ (i as f32 + bias.x) * self.viewport_u_delta + (i as f32 + bias.x) * self.viewport_u_delta
+ (j as f32 + bias.y) * self.viewport_v_delta; + (j as f32 + bias.y) * self.viewport_v_delta;
let r = Ray::new(self.camera_center, pix_sample - self.camera_center); let r = Ray::new(self.center, pix_sample - self.center);
let sample_color = self.ray_color(&r, self.reflect_depth, world); let sample_color = self.ray_color(&r, self.reflect_depth, world);
color = color + sample_color; color = color + sample_color;
} }

View File

@ -22,11 +22,11 @@ fn main() {
fn camera_render() { fn camera_render() {
let fov: f32 = 90.; let fov: f32 = 60.;
let scale = 1; let scale = 1;
let width: i32 = 800/scale; let width: i32 = 800/scale;
let height: i32 = 600/scale; let height: i32 = 600/scale;
let sample_times = 20; let sample_times = 50;
let reflect_depth = 20; let reflect_depth = 20;
@ -44,8 +44,9 @@ fn camera_render() {
fov, fov,
width, width,
width as f32 / height as f32, width as f32 / height as f32,
Point::new(0.0, -0.0, 0.0), Point::new(-2.0, 0.0, -1.0),
1.0, Point::new(0.0, 0.0, -1.0),
Vec3::new(0., 1., 0.),
sample_times, sample_times,
reflect_depth, reflect_depth,
pw pw

View File

@ -1,5 +1,5 @@
use std::{fs::File, io::{BufWriter}}; use std::{fs::File, io::{BufWriter}};
use crate::material::{MaterialKind}; use crate::{material::MaterialKind, vec3};
use crate::ppm_writer::PPMWriter; use crate::ppm_writer::PPMWriter;
/* /*
@ -37,7 +37,9 @@ pub struct Camera<'a> {
// pub aspect_ratio: f32, // pub aspect_ratio: f32,
// pub viewport_width: f32, // pub viewport_width: f32,
// pub viewport_height: f32, // pub viewport_height: f32,
pub camera_center: Point, pub center: Point,
pub look_at: Point,
pub v_up: Vec3,
// pub focal_length: Vec3, // pub focal_length: Vec3,
// pub viewport_u: Vec3, // pub viewport_u: Vec3,
// pub viewport_v: Vec3, // pub viewport_v: Vec3,