Skip to content
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

Non skip pdf in lights HittableList #1668

Open
niccolot opened this issue Jan 4, 2025 · 2 comments
Open

Non skip pdf in lights HittableList #1668

niccolot opened this issue Jan 4, 2025 · 2 comments
Assignees
Milestone

Comments

@niccolot
Copy link

niccolot commented Jan 4, 2025

Hello, if i add to the lights list an object that is not a metal or dielectric the image produced is like

pdfmaterial

i' ve obtained this by putting

// in the original main is glass
auto nonglass = make_shared<lambertian>(color(0.8, 0.2, 0.2));
world.add(make_shared<sphere>(point3(190,90,190), 90, nonglass));

// Light Sources
hittable_list lights;
auto m = shared_ptr<material>();
lights.add(make_shared<quad>(point3(343,554,332), vec3(-130,0,0), vec3(0,0,-105), m));
lights.add(make_shared<sphere>(point3(190, 90, 190), 90, m));

in the main.cpp of therestofyourlife part.

I may not have understood correctly this part of the code and thus it may not be an actual issue but still i wanted to ask this since also a material like a lambertian is still emitting some reflected light

@hollasch hollasch self-assigned this Jan 6, 2025
@hollasch hollasch added this to the v4.0.2 milestone Jan 6, 2025
@niccolot
Copy link
Author

niccolot commented Jan 11, 2025

I' ve looked into it a bit and found out that what's causing the problem is the sphere part of the HittablePDF list belonging to lights:

// main.cpp
HittableList lights;
lights.add(std::make_shared<Quad>(Vec3(213, 554, 227), Vec3(130, 0, 0), Vec3(0, 0, 105), empty_mat));
lights.add(std::make_shared<Sphere>(Vec3(190, 90, 190), 90, empty_mat));

if i select just the sphere part

// camera.cpp
Color color_from_scatter = Color();
    for (const auto& ray_t : srec.scattered_rays) {
        if (ray_t.skip_pdf || ray_t.pdf == nullptr) {
            color_from_scatter += ray_t.attenuation * ray_color(ray_t.skip_pdf_ray, depth-1, world, lights);
        } else {
            auto light_ptr = std::make_shared<HittablePDF>(lights, rec.point()); // lights is the problematic part
            MixturePDF p(light_ptr, ray_t.pdf); 
            Ray scattered = Ray(rec.point(), p.generate(), r.time());
            double pdf_value = p.value(scattered.direction(), r.direction(), -w);
            double scattering_pdf = rec.material()->scattering_pdf(r, rec, scattered, -w);
            Color sample_color = ray_color(scattered, depth-1, world, lights);
                
            color_from_scatter += (ray_t.attenuation * scattering_pdf * sample_color) / pdf_value;
        }
    }
// hittable.pdf
double HittableList::pdf_value(const Vec3& origin, const Vec3& direction) const {
    auto weight = 1.0 / objects.size();
    double sum{};

    for (const auto& obj : objects) {
        sum += weight * obj->pdf_value(origin, direction);
    }

    //return sum;
    return objects[1]->pdf_value(origin, direction);
}

Vec3 HittableList::random(const Vec3& origin) const {
    auto int_size = int(objects.size());
    //return objects[random_int(0, int_size-1)]->random(origin);
return objects[1]->random(origin);
}

i get

hittablelist_element_1

while e.g. with only the light part (index 0) i get a decent image

hittablelist_element_0 png

by comparison, excluding the sphere from the lights list i get

no_sphere_in_lights_list

By checking some values between random and pdf_value i saw that sometimes the vectors are NaNs:

objects[1]->random(origin): -nan -nan -nan

but adding some temporary control like

Vec3 HittableList::random(const Vec3& origin) const {
    auto int_size = int(objects.size());
    auto vec = objects[random_int(0, int_size-1)]->random(origin);

    while (vec.is_nan()) {
        vec = objects[random_int(0, int_size-1)]->random(origin);
    }

    return vec;
}
// vector.h
bool is_nan() const {
            return std::isnan(e[0]) || std::isnan(e[1]) || std::isnan(e[2]);
}

had no change, so this does not seem to be the problem.

@hollasch
Copy link
Collaborator

Thank you for grinding on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants