-
Notifications
You must be signed in to change notification settings - Fork 945
Closed
Milestone
Description
There is a small chance on lambertian materials that the scattered ray has direction (0,0,0):
virtual bool scatter(
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
) const {
vec3 scatter_direction = rec.normal + random_unit_vector();
scattered = ray(rec.p, scatter_direction);
attenuation = albedo;
return true;
}
In line:
vec3 scatter_direction = rec.normal + random_unit_vector();
If the random_unit_vector() is the opposite of the normal.
Later, on the ray_color() function, the scattered ray will be the ray r of the next recursive call:
color ray_color(const ray& r, const hittable& world, int depth) {
hit_record rec;
// If we've exceeded the ray bounce limit, no more light is gathered.
if (depth <= 0)
return color(0,0,0);
if (world.hit(r, 0.001, infinity, rec)) {
ray scattered;
color attenuation;
if (rec.mat_ptr->scatter(r, rec, attenuation, scattered))
return attenuation * ray_color(scattered, world, depth-1);
return color(0,0,0);
}
vec3 unit_direction = unit_vector(r.direction());
auto t = 0.5*(unit_direction.y() + 1.0);
return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0);
}
On the next recursive call, if there is no hit, on this line, unit_direction() will become (-nan, -nan, -nan) since unit_vector() divides by length zero:
vec3 unit_direction = unit_vector(r.direction());
And this will cause ray_color() to return a -nan color.