I'm struggling to understand how the connection step in bidirectional path tracing for the strategy with a single light vertex has to be implemented. The following code essentially shows the PBRT implementation:

pbrt::Spectrum connect_(
    pbrt::Scene const& scene,
    pbrt::Vertex* light_subpath,
    pbrt::Vertex* camera_subpath,
    std::size_t s,
    std::size_t t,
    pbrt::Distribution1D const& light_distribution,
    std::unordered_map<pbrt::Light const*, size_t> const& light_to_index_map,
    pbrt::Camera const& camera,
    pbrt::Sampler& sampler,
    pbrt::Vertex* sampled_endpoint)
    if (s == 1)
        auto const& p = camera_subpath[t - 1];
        if (p.IsConnectible())
            pbrt::Float discrete_probability_of_sampling_light;
            auto const& light = scene.lights[light_distribution.SampleDiscrete(
                sampler.Get1D(), &discrete_probability_of_sampling_light)];

            pbrt::Vector3f wi;
            pbrt::Float density_of_sampling_wi;
            pbrt::VisibilityTester vt;
            pbrt::Spectrum const radiance_arriving_at_p_from_wi
                = light->Sample_Li(p.GetInteraction(), sampler.Get2D(), &wi, &density_of_sampling_wi, &vt);

            if (density_of_sampling_wi > 0 && !radiance_arriving_at_p_from_wi.IsBlack())
                pbrt::EndpointInteraction const light_interaction{ vt.P1(), light.get() };
                pbrt::Spectrum const beta = radiance_arriving_at_p_from_wi * pbrt::AbsDot(wi, p.ns()) /
                    (discrete_probability_of_sampling_light * density_of_sampling_wi);

                *sampled_endpoint = pbrt::Vertex::CreateLight(light_interaction, beta, 0);
                sampled_endpoint->pdfFwd = sampled_endpoint->PdfLightOrigin(
                    scene, p, light_distribution, light_to_index_map);

They ignore the previously generated light vertex light_subpath[0] and sample a new one, *sampled_endpoint, instead.

Maybe it is cause I misunderstand the purpose of the forward density sampled_endpoint->pdfFwd, but shouldn't this density be the density of sampling wi with respect to the solid angle measure and shouldn't this density be precisely discrete_probability_of_sampling_light * density_of_sampling_wi?

I don't understand why it is sampled_endpoint->PdfLightOrigin(scene, p, light_distribution, light_to_index_map) instead. Actually, I don't understand what exactly PdfLightOrigin is computing from the documentation.

In the book, they write that "each vertex has two densities: the first, pdfFwd, stores forward density of the current vertex, which is the probability per unit area of the current vertex as generated by the path sampling algorithm. The second density, pdfRev, is the hypothetical probability density of the vertex if the direction of light transport was reversed—that is, if radiance transport was used in place of importance transport for the camera path and vice versa for the light path."

However, since we are in the connection step, it is not clear to me whether the sampled vertex sampled_endpoint has to be understood as being generated by "radiance transport" or "importance transport". They define the transport mode to be the quantity emitted to the origin of the path so that the mode is "radiance" for the camera and "importance" for the light subpath, respectively.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.