Merge branch 'master' of https://git.dengqn.com/dqn/ray-trace-w1
This commit is contained in:
commit
ff4132edff
|
@ -2,7 +2,7 @@ use std::fs::File;
|
||||||
use std::io::{BufWriter};
|
use std::io::{BufWriter};
|
||||||
|
|
||||||
use crate::hittable::HittableList;
|
use crate::hittable::HittableList;
|
||||||
use crate::math_utils::{clamp, degrees_to_radians};
|
use crate::math_utils::{clamp, degrees_to_radians, random_in_unit_disk};
|
||||||
use crate::ppm_writer::PPMWriter;
|
use crate::ppm_writer::PPMWriter;
|
||||||
use crate::types_defined::{Camera, Color, HitRecord, Point, Ray, Vec3};
|
use crate::types_defined::{Camera, Color, HitRecord, Point, Ray, Vec3};
|
||||||
use rand::rngs::ThreadRng;
|
use rand::rngs::ThreadRng;
|
||||||
|
@ -19,14 +19,17 @@ impl<'a> Camera<'a> {
|
||||||
v_up: Vec3,
|
v_up: Vec3,
|
||||||
sample_times: i8,
|
sample_times: i8,
|
||||||
reflect_depth: i8,
|
reflect_depth: i8,
|
||||||
|
defocus_angle : f32,
|
||||||
|
focal_distance: f32,
|
||||||
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 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.);
|
||||||
let viewport_height = 2. * h * focal_length;
|
let viewport_height = 2. * h * focal_distance;
|
||||||
|
// let viewport_height = 2. * h * focal_length;
|
||||||
|
|
||||||
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);
|
||||||
|
@ -48,11 +51,18 @@ impl<'a> Camera<'a> {
|
||||||
// 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 =
|
||||||
center - focal_length * w - viewport_u / 2.0 - viewport_v / 2.0;
|
center - focal_distance * w - 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;
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate the camera defocus disk basis vectors.
|
||||||
|
let defocus_radius = focal_distance * degrees_to_radians(defocus_angle / 2.0).tan();
|
||||||
|
let defocus_disk_u = u * defocus_radius;
|
||||||
|
let defocus_disk_v = v * defocus_radius;
|
||||||
|
|
||||||
Camera {
|
Camera {
|
||||||
image_width,
|
image_width,
|
||||||
image_height,
|
image_height,
|
||||||
|
@ -65,6 +75,10 @@ impl<'a> Camera<'a> {
|
||||||
// focal_length,
|
// focal_length,
|
||||||
// viewport_u,
|
// viewport_u,
|
||||||
// viewport_v,
|
// viewport_v,
|
||||||
|
defocus_angle,
|
||||||
|
defocus_disk_u,
|
||||||
|
defocus_disk_v,
|
||||||
|
|
||||||
viewport_u_delta,
|
viewport_u_delta,
|
||||||
viewport_v_delta,
|
viewport_v_delta,
|
||||||
viewport_top_left_pixel_center,
|
viewport_top_left_pixel_center,
|
||||||
|
@ -87,11 +101,7 @@ impl<'a> Camera<'a> {
|
||||||
let mut color = Color::new(0.0, 0.0, 0.0);
|
let mut color = Color::new(0.0, 0.0, 0.0);
|
||||||
let rng = &mut rng();
|
let rng = &mut rng();
|
||||||
for _ in 0..self.sample_times {
|
for _ in 0..self.sample_times {
|
||||||
let bias = self.random_square(rng);
|
let r = self.get_ray(i, j);
|
||||||
let pix_sample = self.viewport_top_left_pixel_center
|
|
||||||
+ (i as f32 + bias.x) * self.viewport_u_delta
|
|
||||||
+ (j as f32 + bias.y) * self.viewport_v_delta;
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -114,6 +124,26 @@ impl<'a> Camera<'a> {
|
||||||
// img_content
|
// img_content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn defocus_disk_sample(&self) -> Point {
|
||||||
|
// Returns a random point in the camera defocus disk.
|
||||||
|
let p = random_in_unit_disk();
|
||||||
|
return self.center + (p.x * self.defocus_disk_u) + (p.y * self.defocus_disk_v);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_ray(&self, i: i32, j: i32) -> Ray {
|
||||||
|
let rng = &mut rng();
|
||||||
|
let bias = self.random_square(rng);
|
||||||
|
let pix_sample = self.viewport_top_left_pixel_center
|
||||||
|
+ (i as f32 + bias.x) * self.viewport_u_delta
|
||||||
|
+ (j as f32 + bias.y) * self.viewport_v_delta;
|
||||||
|
let center = if self.defocus_angle < 0. {
|
||||||
|
self.center
|
||||||
|
} else {
|
||||||
|
self.defocus_disk_sample()
|
||||||
|
};
|
||||||
|
Ray::new(center, pix_sample - self.center)
|
||||||
|
}
|
||||||
|
|
||||||
fn ray_color(&self, ray: &Ray, depth: i8, world: &HittableList) -> Vec3 {
|
fn ray_color(&self, ray: &Ray, depth: i8, world: &HittableList) -> Vec3 {
|
||||||
|
|
||||||
// 反射次数
|
// 反射次数
|
||||||
|
|
|
@ -51,6 +51,8 @@ fn camera_render() {
|
||||||
Vec3::new(0., 1., 0.),
|
Vec3::new(0., 1., 0.),
|
||||||
sample_times,
|
sample_times,
|
||||||
reflect_depth,
|
reflect_depth,
|
||||||
|
2.0,
|
||||||
|
1.0,
|
||||||
pw
|
pw
|
||||||
);
|
);
|
||||||
// world
|
// world
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
|
|
||||||
|
use rand::{rng, Rng};
|
||||||
|
|
||||||
use crate::types_defined::{Ray, Vec3};
|
use crate::types_defined::{Ray, Vec3};
|
||||||
|
|
||||||
|
pub fn random_in_unit_disk() -> Vec3 {
|
||||||
|
let rng = &mut rng();
|
||||||
|
loop {
|
||||||
|
let p = Vec3::new(rng.random_range(-1.0..1.0), rng.random_range(-1.0..1.0), 0.0);
|
||||||
|
if (p.length_squared() < 1.0) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn degrees_to_radians(deg: f32) -> f32 {
|
pub fn degrees_to_radians(deg: f32) -> f32 {
|
||||||
deg * PI / 180.
|
deg * PI / 180.
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,10 @@ pub struct Camera<'a> {
|
||||||
// pub focal_length: Vec3,
|
// pub focal_length: Vec3,
|
||||||
// pub viewport_u: Vec3,
|
// pub viewport_u: Vec3,
|
||||||
// pub viewport_v: Vec3,
|
// pub viewport_v: Vec3,
|
||||||
|
pub defocus_angle: f32,
|
||||||
|
pub defocus_disk_u: Vec3,
|
||||||
|
pub defocus_disk_v: Vec3,
|
||||||
|
|
||||||
pub viewport_u_delta: Vec3,
|
pub viewport_u_delta: Vec3,
|
||||||
pub viewport_v_delta: Vec3,
|
pub viewport_v_delta: Vec3,
|
||||||
pub viewport_top_left_pixel_center: Vec3,
|
pub viewport_top_left_pixel_center: Vec3,
|
||||||
|
|
Loading…
Reference in New Issue