9.Diffuse Materials
This commit is contained in:
parent
edd518b54e
commit
71ae83d205
|
@ -12,6 +12,7 @@ impl Camera {
|
||||||
camera_center: Point,
|
camera_center: Point,
|
||||||
focal_length: Vec3,
|
focal_length: Vec3,
|
||||||
sample_times: i8,
|
sample_times: i8,
|
||||||
|
reflect_depth: i8
|
||||||
) -> Self {
|
) -> Self {
|
||||||
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);
|
||||||
|
@ -45,7 +46,8 @@ impl Camera {
|
||||||
viewport_u_delta,
|
viewport_u_delta,
|
||||||
viewport_v_delta,
|
viewport_v_delta,
|
||||||
viewport_top_left_pixel_center,
|
viewport_top_left_pixel_center,
|
||||||
sample_times: sample_times,
|
sample_times,
|
||||||
|
reflect_depth,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +69,7 @@ impl Camera {
|
||||||
+ (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.camera_center, pix_sample - self.camera_center);
|
||||||
let sample_color = self.ray_color(&r, world);
|
let sample_color = self.ray_color(&r, self.reflect_depth, world);
|
||||||
color = color + sample_color;
|
color = color + sample_color;
|
||||||
}
|
}
|
||||||
// color * each sample color
|
// color * each sample color
|
||||||
|
@ -89,15 +91,21 @@ impl Camera {
|
||||||
img_content
|
img_content
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ray_color(&self, ray: &Ray, world: &HittableList) -> Vec3 {
|
fn ray_color(&self, ray: &Ray, depth: i8, world: &HittableList) -> Vec3 {
|
||||||
let hr = world.hit(&ray, 0.0, f32::MAX);
|
|
||||||
|
// 反射次数
|
||||||
|
if depth <= 0 {
|
||||||
|
return Vec3::new(0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 限制出射光线的角度(0.001经验值)
|
||||||
|
let hr = world.hit(&ray, 0.01, f32::MAX);
|
||||||
if hr.t >= 0.0 {
|
if hr.t >= 0.0 {
|
||||||
let normal_color = 0.5 * (hr.normal + Point::new(1.0, 1.0, 1.0));
|
// diffuse normal vec
|
||||||
return if hr.front_face {
|
let diffuse_vec = Vec3::random_unit();
|
||||||
normal_color
|
let lambertian_vec = diffuse_vec + hr.normal;
|
||||||
} else {
|
// 每次反射按0.5计算颜色(反射率 )
|
||||||
Color::new(1.0, 1.0, 1.0) - normal_color
|
return 0.5 * self.ray_color(&Ray::new(ray.point, lambertian_vec), depth - 1, world);
|
||||||
};
|
|
||||||
}
|
}
|
||||||
// v / |v|
|
// v / |v|
|
||||||
let unit_direction = ray.direction / ray.direction.length();
|
let unit_direction = ray.direction / ray.direction.length();
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -22,14 +22,17 @@ fn camera_render() {
|
||||||
2.0,
|
2.0,
|
||||||
Point::new(0.0, 0.0, 0.0),
|
Point::new(0.0, 0.0, 0.0),
|
||||||
Vec3::new(0.0, 0.0, -1.0),
|
Vec3::new(0.0, 0.0, -1.0),
|
||||||
10
|
100,
|
||||||
|
50
|
||||||
);
|
);
|
||||||
// world
|
// world
|
||||||
// world objects(spheres)
|
// world objects(spheres)
|
||||||
let mut world = HittableList::new();
|
let mut world = HittableList::new();
|
||||||
world.put(Box::new(Sphere::new(Point::new(0.0, 0.0, -1.0), 0.5)));
|
world.put(Box::new(Sphere::new(Point::new(0.0, 0.1, -1.0), 0.5)));
|
||||||
world.put(Box::new(Sphere::new(Point::new(0.1, -100.0, -0.0), 100.0)));
|
world.put(Box::new(Sphere::new(Point::new(0.3, 0.1, -1.0), 0.1)));
|
||||||
world.put(Box::new(Sphere::new(Point::new(-0.5, 0.2, -0.5), 0.2)));
|
world.put(Box::new(Sphere::new(Point::new(-0.5, 0.0, -1.0), 0.3)));
|
||||||
|
world.put(Box::new(Sphere::new(Point::new(0.0, -100.0, -1.0), 100.0)));
|
||||||
|
world.put(Box::new(Sphere::new(Point::new(-0.5, 0.2, -0.5), 0.4)));
|
||||||
|
|
||||||
let ppm_content = camera.render(&world);
|
let ppm_content = camera.render(&world);
|
||||||
write_image(
|
write_image(
|
||||||
|
|
|
@ -43,7 +43,8 @@ pub struct Camera {
|
||||||
pub viewport_top_left_pixel_center: Vec3,
|
pub viewport_top_left_pixel_center: Vec3,
|
||||||
|
|
||||||
// sample times
|
// sample times
|
||||||
pub sample_times: i8
|
pub sample_times: i8,
|
||||||
|
pub reflect_depth: i8
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
28
src/vec3.rs
28
src/vec3.rs
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
use std::{fmt::Display, ops::{Add, AddAssign, Div, Mul, MulAssign, Sub}};
|
use std::{fmt::Display, ops::{Add, AddAssign, Div, Mul, MulAssign, Sub}};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
use crate::types_defined::Vec3;
|
use crate::types_defined::Vec3;
|
||||||
|
|
||||||
impl Display for Vec3 {
|
impl Display for Vec3 {
|
||||||
|
@ -36,6 +37,33 @@ impl Vec3 {
|
||||||
return self.length_squared().sqrt();
|
return self.length_squared().sqrt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn random_range(min: f32, max: f32) -> Self {
|
||||||
|
let rng = &mut thread_rng();
|
||||||
|
Vec3::new(rng.gen_range(min..max), rng.gen_range(min..max), rng.gen_range(min..max))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn random() -> Self {
|
||||||
|
let rng = &mut thread_rng();
|
||||||
|
Vec3::new(rng.r#gen(), rng.r#gen(), rng.r#gen())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn random_unit() -> Self {
|
||||||
|
loop {
|
||||||
|
let v = Vec3::random();
|
||||||
|
if f32::MIN < v.length_squared() && v.length_squared() <= 1.0 {
|
||||||
|
return v / v.length_squared();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn random_unit_on_hemisphere(point_normal: Vec3) -> Self {
|
||||||
|
let on_unit_sphere = Vec3::random_unit();
|
||||||
|
if on_unit_sphere.dot(point_normal) > 0.0 {
|
||||||
|
on_unit_sphere
|
||||||
|
} else {
|
||||||
|
Vec3::new(0.0, 0.0, 0.0) - on_unit_sphere
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add for Vec3 {
|
impl Add for Vec3 {
|
||||||
|
|
Loading…
Reference in New Issue