OrthographicCamera::generate_ray_differential was incorrect
flarelee opened this issue · comments
OrthographicCamera::generate_ray_differential
was incorrect.
my fixed code
fn generate_ray_differential(&self, sample: &CameraSample, ray: &mut Ray) -> Float {
// TODO: ProfilePhase prof(Prof::GenerateCameraRay);
// compute raster and camera sample positions
let p_film: Point3f = Point3f {
x: sample.p_film.x,
y: sample.p_film.y,
z: 0.0,
};
let p_camera: Point3f = self.raster_to_camera.transform_point(&p_film);
*ray = Ray {
o: p_camera,
d: Vector3f {
x: 0.0,
y: 0.0,
z: 1.0,
},
t_max: std::f32::INFINITY,
time: lerp(sample.time, self.shutter_open, self.shutter_close),
medium: None,
differential: None,
};
// modify ray for depth of field
if self.lens_radius > 0.0 as Float {
// sample point on lens
let p_lens: Point2f = concentric_sample_disk(&sample.p_lens) * self.lens_radius;
// compute point on plane of focus
let ft: Float = self.focal_distance / ray.d.z;
let p_focus: Point3f = ray.position(ft);
// update ray for effect of lens
ray.o = Point3f {
x: p_lens.x,
y: p_lens.y,
z: 0.0 as Float,
};
ray.d = (p_focus - ray.o).normalize();
}
// compute offset rays for _OrthographicCamera_ ray differentials
if self.lens_radius > 0.0 as Float {
// compute _OrthographicCamera_ ray differentials accounting for lens
// sample point on lens
let p_lens: Point2f = concentric_sample_disk(&sample.p_lens) * self.lens_radius;
let ft: Float = self.focal_distance / ray.d.z;
let p_focus: Point3f = p_camera
+ self.dx_camera
+ (Vector3f {
x: 0.0 as Float,
y: 0.0 as Float,
z: 1.0 as Float,
} * ft);
let rx_origin = Point3f {
x: p_lens.x,
y: p_lens.y,
z: 0.0 as Float,
};
let ry_origin = Point3f {
x: p_lens.x,
y: p_lens.y,
z: 0.0 as Float,
};
let diff = RayDifferential {
rx_origin: rx_origin,
rx_direction: (p_focus - rx_origin).normalize(),
ry_origin: ry_origin,
ry_direction: (p_focus - ry_origin).normalize(),
};
// replace differential
ray.differential = Some(diff);
} else {
let diff: RayDifferential = RayDifferential {
rx_origin: ray.o + self.dx_camera,
ry_origin: ray.o + self.dy_camera,
rx_direction: ray.d,
ry_direction: ray.d,
};
ray.differential = Some(diff);
}
// ray->medium = medium;
if let Some(ref medium_arc) = self.medium {
ray.medium = Some(medium_arc.clone());
} else {
ray.medium = None;
}
*ray = self.camera_to_world.transform_ray(ray);
1.0
}
Can you explain a bit, what was actually wrong in the current implementation?