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
|
||||
let viewport_v_delta = viewport_v / (image_height as f32);
|
||||
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
|
||||
let viewport_top_left_pixel_center =
|
||||
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),
|
||||
);
|
||||
|
||||
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);
|
||||
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 hc = &mut HitRecord{
|
||||
t: hit_record.t,
|
||||
|
@ -126,42 +124,22 @@ impl<'a> Camera<'a> {
|
|||
let hit_c = match hit_m {
|
||||
Some(mk) => {
|
||||
let mc = match mk {
|
||||
MaterialKind::Lambertian(l) => {
|
||||
if l.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)
|
||||
}
|
||||
},
|
||||
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)
|
||||
}
|
||||
}
|
||||
// MaterialKind::Lambertian(l) => l.albedo,
|
||||
MaterialKind::Lambertian(l) => self.scatter_color(ray, hc, l, depth, world),
|
||||
MaterialKind::Metal(m) => self.scatter_color(ray, hc, m, depth, world),
|
||||
};
|
||||
return mc
|
||||
mc
|
||||
},
|
||||
None => {
|
||||
// if hit_record.t >= 0.0 {
|
||||
// // diffuse normal vec
|
||||
// let diffuse_vec = Vec3::random_unit();
|
||||
// let lambertian_vec = diffuse_vec + hit_record.normal;
|
||||
// // 每次反射按0.5计算颜色(反射率 )
|
||||
// return 0.5 * self.ray_color(&Ray::new(ray.point, lambertian_vec), depth - 1, world);
|
||||
// }
|
||||
if hit_record.t >= 0.0 {
|
||||
let diffuse_vec = Vec3::random_unit();
|
||||
let lambertian_vec = diffuse_vec + hit_record.normal;
|
||||
0.5 * self.ray_color(&Ray::new(ray.point, lambertian_vec), depth - 1, world)
|
||||
} else {
|
||||
Color::new(0.0, 0.0, 0.0)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return hit_c;
|
||||
}
|
||||
|
||||
|
@ -176,4 +154,32 @@ impl<'a> Camera<'a> {
|
|||
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)
|
||||
}
|
||||
|
||||
|
||||
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 {
|
||||
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;
|
||||
closest_so_far = temp_hit_record.t;
|
||||
hit_record.t = temp_hit_record.t;
|
||||
|
@ -47,9 +47,10 @@ impl HittableList {
|
|||
} else {
|
||||
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() {
|
||||
|
||||
let width: i32 = 1920;
|
||||
let height: i32 = 1080;
|
||||
let width: i32 = 800/2;
|
||||
let height: i32 = 600/2;
|
||||
let pw_r = PPMWriter::new(
|
||||
BufWriter::new(File::create("./target/ray_sphere_normal_scene_render.ppm").unwrap()),
|
||||
width, height);
|
||||
|
@ -37,28 +37,30 @@ fn camera_render() {
|
|||
|
||||
let mut camera: Camera = Camera::new(
|
||||
width,
|
||||
16.0 / 9.0,
|
||||
4.0 / 3.0,
|
||||
2.0,
|
||||
Point::new(0.0, -0.5, 0.0),
|
||||
Vec3::new(0.0, 0.0, -0.5),
|
||||
100,
|
||||
50,
|
||||
Point::new(0.0, -0.0, 0.0),
|
||||
Vec3::new(0.0, 0.0, 1.0),
|
||||
127,
|
||||
127,
|
||||
pw
|
||||
);
|
||||
// world
|
||||
// world objects(spheres)
|
||||
let mut world = HittableList::new();
|
||||
|
||||
let plane_m = Some(MaterialKind::Lambertian(Lambertian{albedo: Color::new(0.3, 0.2, 0.5)}));
|
||||
// let plane2_m = Some(MaterialKind::Metal(Metal{albedo: Color::new(0.999, 0.999, 0.999)}));
|
||||
let center_m = Some(MaterialKind::Lambertian(Lambertian{albedo: Color::new(0.1, 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.784,0.784,0.784)}));
|
||||
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_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)}));
|
||||
|
||||
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.2), 0.5, center_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(0.0, 0.0, -1.0), 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.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(0.0, -25.5, -1.0), 25.0, plane_m)));
|
||||
|
||||
camera.render(&world);
|
||||
// write_image(
|
||||
|
|
|
@ -28,12 +28,13 @@ impl Clone for Lambertian {
|
|||
impl Material for Lambertian {
|
||||
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);
|
||||
|
||||
if near_zero(scatter_direction) {
|
||||
scattered.direction = hit_record.normal;
|
||||
}
|
||||
// if near_zero(scatter_direction) {
|
||||
// scattered.direction = r_in.direction;
|
||||
// }
|
||||
|
||||
*scattered = Ray::new(hit_record.p, scatter_direction);
|
||||
*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 {
|
||||
const EPSILON: f32 = 1e-8;
|
||||
const EPSILON: f32 = 1e-4;
|
||||
|
||||
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 {
|
||||
root = far;
|
||||
if root <= t_min || root >= t_max {
|
||||
// hit_record.t = -1.0;
|
||||
hit_record.t = -1.0;
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue