-
Notifications
You must be signed in to change notification settings - Fork 891
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Book 3.8.3: What are we supposed to do with the returned material::scatter() pdf value? #1543
Comments
lol glad to see this, i was quite confused. i still honestly dont know what to do. are you able to give a quick answer now? This is what I attempted to do... im assuming i initialize an empty value, but im not sure about the initial value, whether it should be 0 or 1 / 2 * pi fn ray_color<T: Hittable>(&self, r: Ray, depth: u32, world: &T) -> Color {
if depth == 0 {
return Color::new(0, 0, 0);
}
let mut rec = HitRecord::default();
if !world.hit(r, Interval::new(0.001, f64::INFINITY), &mut rec) {
return self.background;
}
let mut scattered = Ray::default();
let mut attenuation = Color::default();
let mut pdf = 0.0; //1.0 / (2.0 * std::f64::consts::PI);
let color_from_emission = rec
.mat
.as_ref()
.expect("material is present")
.emitted(rec.u, rec.v, rec.p);
// clone the material, and move the hit record
if !rec.mat.as_ref().expect("material is present").scatter(
r,
&rec,
&mut attenuation,
&mut scattered,
&mut pdf,
) {
return color_from_emission;
}
let scattering_pdf = rec
.mat
.as_ref()
.expect("material is present")
.scattering_pdf(r, &rec, &scattered);
let color_from_scatter =
(attenuation * scattering_pdf * self.ray_color(scattered, depth - 1, world)) / pdf;
color_from_emission + color_from_scatter
} |
In case anyone comes across this... just proceed to the next section and it mostly answers it. Heres my finished function (after this section) which seems to be caught up. fn ray_color<T: Hittable>(&self, r: Ray, depth: u32, world: &T) -> Color {
if depth == 0 {
return Color::new(0, 0, 0);
}
let mut rec = HitRecord::default();
if !world.hit(r, Interval::new(0.001, f64::INFINITY), &mut rec) {
return self.background;
}
let mut scattered = Ray::default();
let mut attenuation = Color::default();
let mut pdf = 0.0;
let color_from_emission = rec
.mat
.as_ref()
.expect("material is present")
.emitted(rec.u, rec.v, rec.p);
if !rec.mat.as_ref().expect("material is present").scatter(
r,
&rec,
&mut attenuation,
&mut scattered,
&mut pdf,
) {
return color_from_emission;
}
let mut rng = rand::thread_rng();
let on_light = Point3::new(rng.gen_range(213.0..343.0), 554.0, rng.gen_range(227.0..332.0));
let mut to_light = on_light - rec.p;
let distance_squared = to_light.length_squared();
to_light = unit_vector(to_light);
if dot(to_light, rec.normal) < 0.0 {
return color_from_emission;
}
let light_area = (343.0 - 213.0) * (332.0 - 227.0);
let light_cosine = f64::abs(to_light.y);
if light_cosine < 0.000001 {
return color_from_emission;
}
pdf = distance_squared / (light_cosine * light_area);
scattered = Ray::new(rec.p, to_light, r.time);
let scattering_pdf = rec
.mat
.as_ref()
.expect("material is present")
.scattering_pdf(r, &rec, &scattered);
let color_from_scatter =
(attenuation * scattering_pdf * self.ray_color(scattered, depth - 1, world)) / pdf;
color_from_emission + color_from_scatter
} impl Material for Lambertian {
fn scatter(
&self,
ray_in: Ray,
rec: &HitRecord,
attenuation: &mut Color,
scattered: &mut Ray,
pdf: &mut f64,
) -> bool {
let uvw = Onb::new_from_w(rec.normal);
let scatter_direction = uvw.local_from_vec(random_cosine_direction());
*scattered = Ray::new(rec.p, unit_vector(scatter_direction), ray_in.time);
*attenuation = self.tex.value(rec.u, rec.v, rec.p);
*pdf = dot(uvw.w(), scattered.direction) / std::f64::consts::PI;
true
}
fn scattering_pdf(&self, ray_in: Ray, rec: &HitRecord, scattered: &Ray) -> f64 {
const SCATTERING_PDF: f64 = 1.0 / (2.0 * std::f64::consts::PI);
SCATTERING_PDF
}
}
impl Material for Isotropic {
fn scatter(
&self,
ray_in: Ray,
rec: &HitRecord,
attenuation: &mut Color,
scattered: &mut Ray,
pdf: &mut f64,
) -> bool {
*scattered = Ray::new(rec.p, random_unit_vector(), ray_in.time);
*attenuation = self.tex.value(rec.u, rec.v, rec.p);
*pdf = 1.0 / (4.0 * std::f64::consts::PI);
true
}
fn scattering_pdf(&self, _ray_in: Ray, _rec: &HitRecord, _scattered: &Ray) -> f64 {
1.0 / (4.0 * std::f64::consts::PI)
}
} |
We add the double pdf value reference to the
material::scatter()
functions, but don't show the corresponding update tocamera::ray_color()
, let alone how to use it.The text was updated successfully, but these errors were encountered: