Skip to content

Bug: Image corruption if lambertian scattered ray direction is (0,0,0). #619

@Teledhil

Description

@Teledhil

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions