bug fix
This commit is contained in:
parent
cbd072af4a
commit
2018b02e02
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
|
@ -34,7 +34,7 @@ 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 =
|
||||||
camera_center + focal_length - viewport_u / 2.0 - viewport_v / 2.0;
|
camera_center - focal_length - 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;
|
||||||
|
@ -89,7 +89,7 @@ impl<'a> Camera<'a> {
|
||||||
clamp(color.z, 0.0, 1.0),
|
clamp(color.z, 0.0, 1.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.ppm_file_writer.write(color.to_color());
|
self.ppm_file_writer.write(color_clamped.to_color());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +113,6 @@ impl<'a> Camera<'a> {
|
||||||
};
|
};
|
||||||
let hit = world.hit(&ray, 0.001, f32::MAX, hit_record);
|
let hit = world.hit(&ray, 0.001, f32::MAX, hit_record);
|
||||||
if hit {
|
if hit {
|
||||||
let scatted = &mut Ray::new(Point::new(0.0, 0.0, 0.0), Vec3::random());
|
|
||||||
let attenuation = &mut Color::new(1.0, 1.0, 1.0);
|
|
||||||
let hit_m = &hit_record.material;
|
let hit_m = &hit_record.material;
|
||||||
let hc = &mut HitRecord{
|
let hc = &mut HitRecord{
|
||||||
t: hit_record.t,
|
t: hit_record.t,
|
||||||
|
@ -126,42 +124,22 @@ impl<'a> Camera<'a> {
|
||||||
let hit_c = match hit_m {
|
let hit_c = match hit_m {
|
||||||
Some(mk) => {
|
Some(mk) => {
|
||||||
let mc = match mk {
|
let mc = match mk {
|
||||||
MaterialKind::Lambertian(l) => {
|
// MaterialKind::Lambertian(l) => l.albedo,
|
||||||
if l.scatter(ray, hc, attenuation, scatted) {
|
MaterialKind::Lambertian(l) => self.scatter_color(ray, hc, l, depth, world),
|
||||||
let r_c = self.ray_color(scatted, depth - 1, world);
|
MaterialKind::Metal(m) => self.scatter_color(ray, hc, m, depth, world),
|
||||||
let sc_color = Vec3::new(attenuation.x * r_c.x, attenuation.y * r_c.y, attenuation.z * r_c.z);
|
|
||||||
// *attenuation * ;
|
|
||||||
Color::new(sc_color.x, sc_color.y, sc_color.z)
|
|
||||||
} else {
|
|
||||||
Color::new(0.0, 0.0, 0.0)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MaterialKind::Metal(m) => {
|
|
||||||
if m.scatter(ray, hc, attenuation, scatted) {
|
|
||||||
let r_c = self.ray_color(scatted, depth - 1, world);
|
|
||||||
let sc_color = Vec3::new(attenuation.x * r_c.x, attenuation.y * r_c.y, attenuation.z * r_c.z);
|
|
||||||
// *attenuation * ;
|
|
||||||
|
|
||||||
Color::new(sc_color.x, sc_color.y, sc_color.z)
|
|
||||||
} else {
|
|
||||||
Color::new(0.0, 0.0, 0.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
return mc
|
mc
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
// if hit_record.t >= 0.0 {
|
if hit_record.t >= 0.0 {
|
||||||
// // diffuse normal vec
|
let diffuse_vec = Vec3::random_unit();
|
||||||
// let diffuse_vec = Vec3::random_unit();
|
let lambertian_vec = diffuse_vec + hit_record.normal;
|
||||||
// let lambertian_vec = diffuse_vec + hit_record.normal;
|
0.5 * self.ray_color(&Ray::new(ray.point, lambertian_vec), depth - 1, world)
|
||||||
// // 每次反射按0.5计算颜色(反射率 )
|
} else {
|
||||||
// return 0.5 * self.ray_color(&Ray::new(ray.point, lambertian_vec), depth - 1, world);
|
|
||||||
// }
|
|
||||||
Color::new(0.0, 0.0, 0.0)
|
Color::new(0.0, 0.0, 0.0)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return hit_c;
|
return hit_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,4 +154,32 @@ impl<'a> Camera<'a> {
|
||||||
fn random_square(&self, rng: &mut ThreadRng) -> Vec3 {
|
fn random_square(&self, rng: &mut ThreadRng) -> Vec3 {
|
||||||
Vec3::new(rng.gen_range(-0.5..0.1), rng.gen_range(-0.5..0.1), 0.0)
|
Vec3::new(rng.gen_range(-0.5..0.1), rng.gen_range(-0.5..0.1), 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn scatter_color(
|
||||||
|
&self,
|
||||||
|
ray: &Ray,
|
||||||
|
hc: &mut HitRecord,
|
||||||
|
material: &impl Material,
|
||||||
|
depth: i8,
|
||||||
|
world: &HittableList,
|
||||||
|
) -> Color {
|
||||||
|
let mut scatted = Ray::new(Point::new(0.0, 0.0, 0.0), Vec3::random());
|
||||||
|
let mut attenuation = Color::new(1.0, 1.0, 1.0);
|
||||||
|
if material.scatter(ray, hc, &mut attenuation, &mut scatted) {
|
||||||
|
let r_c = self.ray_color(&scatted, depth - 1, world);
|
||||||
|
let sc_color = Vec3::new(
|
||||||
|
attenuation.x * r_c.x,
|
||||||
|
attenuation.y * r_c.y,
|
||||||
|
attenuation.z * r_c.z,
|
||||||
|
);
|
||||||
|
Color::new(sc_color.x, sc_color.y, sc_color.z)
|
||||||
|
} else {
|
||||||
|
Color::new(0.0, 0.0, 0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ impl HittableList {
|
||||||
|
|
||||||
for object in &self.objects {
|
for object in &self.objects {
|
||||||
let hit = object.hit(r, t_min, closest_so_far, temp_hit_record);
|
let hit = object.hit(r, t_min, closest_so_far, temp_hit_record);
|
||||||
if hit {
|
if hit && temp_hit_record.t < closest_so_far {
|
||||||
hits = true;
|
hits = true;
|
||||||
closest_so_far = temp_hit_record.t;
|
closest_so_far = temp_hit_record.t;
|
||||||
hit_record.t = temp_hit_record.t;
|
hit_record.t = temp_hit_record.t;
|
||||||
|
@ -47,9 +47,10 @@ impl HittableList {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
if temp_hit_record.t >= 0.0 {
|
|
||||||
return true;
|
// if temp_hit_record.t >= 0.0 {
|
||||||
}
|
// return true;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
src/main.rs
28
src/main.rs
|
@ -23,8 +23,8 @@ fn main() {
|
||||||
|
|
||||||
fn camera_render() {
|
fn camera_render() {
|
||||||
|
|
||||||
let width: i32 = 1920;
|
let width: i32 = 800/2;
|
||||||
let height: i32 = 1080;
|
let height: i32 = 600/2;
|
||||||
let pw_r = PPMWriter::new(
|
let pw_r = PPMWriter::new(
|
||||||
BufWriter::new(File::create("./target/ray_sphere_normal_scene_render.ppm").unwrap()),
|
BufWriter::new(File::create("./target/ray_sphere_normal_scene_render.ppm").unwrap()),
|
||||||
width, height);
|
width, height);
|
||||||
|
@ -37,28 +37,30 @@ fn camera_render() {
|
||||||
|
|
||||||
let mut camera: Camera = Camera::new(
|
let mut camera: Camera = Camera::new(
|
||||||
width,
|
width,
|
||||||
16.0 / 9.0,
|
4.0 / 3.0,
|
||||||
2.0,
|
2.0,
|
||||||
Point::new(0.0, -0.5, 0.0),
|
Point::new(0.0, -0.0, 0.0),
|
||||||
Vec3::new(0.0, 0.0, -0.5),
|
Vec3::new(0.0, 0.0, 1.0),
|
||||||
100,
|
127,
|
||||||
50,
|
127,
|
||||||
pw
|
pw
|
||||||
);
|
);
|
||||||
// world
|
// world
|
||||||
// world objects(spheres)
|
// world objects(spheres)
|
||||||
let mut world = HittableList::new();
|
let mut world = HittableList::new();
|
||||||
|
|
||||||
let plane_m = Some(MaterialKind::Lambertian(Lambertian{albedo: Color::new(0.3, 0.2, 0.5)}));
|
let plane_m = Some(MaterialKind::Lambertian(Lambertian{albedo: Color::new(0.899, 0.899, 0.999)}));
|
||||||
// let plane2_m = Some(MaterialKind::Metal(Metal{albedo: Color::new(0.999, 0.999, 0.999)}));
|
let plane2_m = Some(MaterialKind::Metal(Metal{albedo: Color::new(0.784,0.784,0.784)}));
|
||||||
let center_m = Some(MaterialKind::Lambertian(Lambertian{albedo: Color::new(0.1, 0.2, 0.5)}));
|
let center_m = Some(MaterialKind::Lambertian(Lambertian{albedo: Color::new(0.5, 0.5, 0.5)}));
|
||||||
let left_m = Some(MaterialKind::Metal(Metal{albedo: Color::new(0.799, 0.599, 0.799)}));
|
let left_m = Some(MaterialKind::Metal(Metal{albedo: Color::new(0.799, 0.599, 0.799)}));
|
||||||
|
let left_behind_m = Some(MaterialKind::Lambertian(Lambertian{albedo: Color::new(0.799, 0.599, 0.599)}));
|
||||||
let right_m = Some(MaterialKind::Metal(Metal{albedo: Color::new(0.8, 0.6, 0.2)}));
|
let right_m = Some(MaterialKind::Metal(Metal{albedo: Color::new(0.8, 0.6, 0.2)}));
|
||||||
|
|
||||||
world.put(Box::new(Sphere::new(Point::new(0.0, -100.5, -1.2), 100.0, plane_m)));
|
world.put(Box::new(Sphere::new(Point::new(0.0, 0.0, -1.0), 0.5, center_m)));
|
||||||
world.put(Box::new(Sphere::new(Point::new(0.0, 0.0, -1.2), 0.5, center_m)));
|
world.put(Box::new(Sphere::new(Point::new(-1.0, 0.0, -1.0), 0.5, left_m)));
|
||||||
world.put(Box::new(Sphere::new(Point::new(-2.0, 0.0, -1.0), 1.0, left_m)));
|
world.put(Box::new(Sphere::new(Point::new(-2.5, 1.5, -3.5), 1.5, left_behind_m)));
|
||||||
world.put(Box::new(Sphere::new(Point::new(1.0, 0.0, -1.0), 0.5, right_m)));
|
world.put(Box::new(Sphere::new(Point::new(1.0, 0.0, -1.0), 0.5, right_m)));
|
||||||
|
world.put(Box::new(Sphere::new(Point::new(0.0, -25.5, -1.0), 25.0, plane_m)));
|
||||||
|
|
||||||
camera.render(&world);
|
camera.render(&world);
|
||||||
// write_image(
|
// write_image(
|
||||||
|
|
|
@ -28,12 +28,13 @@ impl Clone for Lambertian {
|
||||||
impl Material for Lambertian {
|
impl Material for Lambertian {
|
||||||
fn scatter(&self, r_in: &Ray, hit_record: &mut HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
|
fn scatter(&self, r_in: &Ray, hit_record: &mut HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
|
||||||
|
|
||||||
let scatter_direction = hit_record.normal + Vec3::random_unit();
|
let scatter_direction = r_in.direction + Vec3::random_unit_on_hemisphere(hit_record.normal);
|
||||||
|
// hit_record.normal + Vec3::random_unit();
|
||||||
// let scatter_direction = reflect(r_in.direction, hit_record.normal);
|
// let scatter_direction = reflect(r_in.direction, hit_record.normal);
|
||||||
|
|
||||||
if near_zero(scatter_direction) {
|
// if near_zero(scatter_direction) {
|
||||||
scattered.direction = hit_record.normal;
|
// scattered.direction = r_in.direction;
|
||||||
}
|
// }
|
||||||
|
|
||||||
*scattered = Ray::new(hit_record.p, scatter_direction);
|
*scattered = Ray::new(hit_record.p, scatter_direction);
|
||||||
*attenuation = self.albedo.clone();
|
*attenuation = self.albedo.clone();
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub fn clamp(value: f32, low: f32, high: f32) -> f32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn near_zero(v: Vec3) -> bool {
|
pub fn near_zero(v: Vec3) -> bool {
|
||||||
const EPSILON: f32 = 1e-8;
|
const EPSILON: f32 = 1e-4;
|
||||||
|
|
||||||
v.x.abs() < EPSILON && v.y.abs() < EPSILON && v.z.abs() < EPSILON
|
v.x.abs() < EPSILON && v.y.abs() < EPSILON && v.z.abs() < EPSILON
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ impl hittable::Hittable for Sphere {
|
||||||
if root <= t_min || root >= t_max {
|
if root <= t_min || root >= t_max {
|
||||||
root = far;
|
root = far;
|
||||||
if root <= t_min || root >= t_max {
|
if root <= t_min || root >= t_max {
|
||||||
// hit_record.t = -1.0;
|
hit_record.t = -1.0;
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue