当前位置: 首页>>代码示例>>C++>>正文


C++ SurfaceInteraction::Le方法代码示例

本文整理汇总了C++中SurfaceInteraction::Le方法的典型用法代码示例。如果您正苦于以下问题:C++ SurfaceInteraction::Le方法的具体用法?C++ SurfaceInteraction::Le怎么用?C++ SurfaceInteraction::Le使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在SurfaceInteraction的用法示例。


在下文中一共展示了SurfaceInteraction::Le方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: Li

Spectrum DirectLightingIntegrator::Li(const RayDifferential &ray,
                                      const Scene &scene, Sampler &sampler,
                                      MemoryArena &arena, int depth) const {
    ProfilePhase p(Prof::SamplerIntegratorLi);
    Spectrum L(0.f);
    // Find closest ray intersection or return background radiance
    SurfaceInteraction isect;
    if (!scene.Intersect(ray, &isect)) {
        for (const auto &light : scene.lights) L += light->Le(ray);
        return L;
    }

    // Compute scattering functions for surface interaction
    isect.ComputeScatteringFunctions(ray, arena);
    if (!isect.bsdf)
        return Li(isect.SpawnRay(ray.d), scene, sampler, arena, depth);
    Vector3f wo = isect.wo;
    // Compute emitted light if ray hit an area light source
    L += isect.Le(wo);
    if (scene.lights.size() > 0) {
        // Compute direct lighting for _DirectLightingIntegrator_ integrator
        if (strategy == LightStrategy::UniformSampleAll)
            L += UniformSampleAllLights(isect, scene, arena, sampler,
                                        nLightSamples);
        else
            L += UniformSampleOneLight(isect, scene, arena, sampler);
    }
    if (depth + 1 < maxDepth) {
        Vector3f wi;
        // Trace rays for specular reflection and refraction
        L += SpecularReflect(ray, isect, scene, sampler, arena, depth);
        L += SpecularTransmit(ray, isect, scene, sampler, arena, depth);
    }
    return L;
}
开发者ID:Drooids,项目名称:pbrt-v3,代码行数:35,代码来源:directlighting.cpp

示例2: Li

// WhittedIntegrator Method Definitions
Spectrum WhittedIntegrator::Li(const RayDifferential &ray, const Scene &scene,
                               Sampler &sampler, MemoryArena &arena,
                               int depth) const {
    Spectrum L(0.);
    // Find closest ray intersection or return background radiance
    SurfaceInteraction isect;
    if (!scene.Intersect(ray, &isect)) {
        for (const auto &light : scene.lights) L += light->Le(ray);
        return L;
    }

    // Compute emitted and reflected light at ray intersection point

    // Initialize common variables for Whitted integrator
    const Normal3f &n = isect.shading.n;
    Vector3f wo = isect.wo;

    // Compute scattering functions for surface interaction
    isect.ComputeScatteringFunctions(ray, arena);
    if (!isect.bsdf)
        return Li(isect.SpawnRay(ray.d), scene, sampler, arena, depth);

    // Compute emitted light if ray hit an area light source
    L += isect.Le(wo);

    // Add contribution of each light source
    for (const auto &light : scene.lights) {
        Vector3f wi;
        Float pdf;
        VisibilityTester visibility;
        Spectrum Li =
            light->Sample_Li(isect, sampler.Get2D(), &wi, &pdf, &visibility);
        if (Li.IsBlack() || pdf == 0) continue;
        Spectrum f = isect.bsdf->f(wo, wi);
        if (!f.IsBlack() && visibility.Unoccluded(scene))
            L += f * Li * AbsDot(wi, n) / pdf;
    }
    if (depth + 1 < maxDepth) {
        // Trace rays for specular reflection and refraction
        L += SpecularReflect(ray, isect, scene, sampler, arena, depth);
        L += SpecularTransmit(ray, isect, scene, sampler, arena, depth);
    }
    return L;
}
开发者ID:AndreaLoforte,项目名称:pbrt-v3,代码行数:45,代码来源:whitted.cpp

示例3: Li

// VolPathIntegrator Method Definitions
Spectrum VolPathIntegrator::Li(const RayDifferential &r, const Scene &scene,
                               Sampler &sampler, MemoryArena &arena,
                               int depth) const {
    ProfilePhase p(Prof::SamplerIntegratorLi);
    Spectrum L(0.f), alpha(1.f);
    RayDifferential ray(r);
    bool specularBounce = false;
    for (int bounces = 0;; ++bounces) {
        // Store intersection into _isect_
        SurfaceInteraction isect;
        bool foundIntersection = scene.Intersect(ray, &isect);

        // Sample the participating medium, if present
        MediumInteraction mi;
        if (ray.medium) alpha *= ray.medium->Sample(ray, sampler, arena, &mi);
        if (alpha.IsBlack()) break;

        // Handle an interaction with a medium or a surface
        if (mi.IsValid()) {
            // Handle medium scattering case
            Vector3f wo = -ray.d, wi;
            L += alpha * UniformSampleOneLight(mi, scene, sampler, arena, true);
            Point2f phaseSample = sampler.Get2D();
            mi.phase->Sample_p(wo, &wi, phaseSample);
            ray = mi.SpawnRay(wi);
        } else {
            // Handle surface scattering case

            // Possibly add emitted light and terminate
            if (bounces == 0 || specularBounce) {
                // Add emitted light at path vertex or from the environment
                if (foundIntersection)
                    L += alpha * isect.Le(-ray.d);
                else
                    for (const auto &light : scene.lights)
                        L += alpha * light->Le(ray);
            }
            if (!foundIntersection || bounces >= maxDepth) break;

            // Compute scattering functions and skip over medium boundaries
            isect.ComputeScatteringFunctions(ray, arena, true);
            if (!isect.bsdf) {
                ray = isect.SpawnRay(ray.d);
                bounces--;
                continue;
            }

            // Sample illumination from lights to find attenuated path
            // contribution
            L += alpha *
                 UniformSampleOneLight(isect, scene, sampler, arena, true);

            // Sample BSDF to get new path direction
            Vector3f wo = -ray.d, wi;
            Float pdf;
            BxDFType flags;
            Spectrum f = isect.bsdf->Sample_f(wo, &wi, sampler.Get2D(), &pdf,
                                              BSDF_ALL, &flags);
            if (f.IsBlack() || pdf == 0.f) break;
            alpha *= f * AbsDot(wi, isect.shading.n) / pdf;
            Assert(std::isinf(alpha.y()) == false);
            specularBounce = (flags & BSDF_SPECULAR) != 0;
            ray = isect.SpawnRay(wi);

            // Account for attenuated subsurface scattering, if applicable
            if (isect.bssrdf && (flags & BSDF_TRANSMISSION)) {
                // Importance sample the BSSRDF
                SurfaceInteraction pi;
                Spectrum S = isect.bssrdf->Sample_S(
                    scene, sampler.Get1D(), sampler.Get2D(), arena, &pi, &pdf);
#ifndef NDEBUG
                Assert(std::isinf(alpha.y()) == false);
#endif
                if (S.IsBlack() || pdf == 0) break;
                alpha *= S / pdf;

                // Account for the attenuated direct subsurface scattering
                // component
                L += alpha *
                     UniformSampleOneLight(pi, scene, sampler, arena, true);

                // Account for the indirect subsurface scattering component
                Spectrum f = pi.bsdf->Sample_f(pi.wo, &wi, sampler.Get2D(),
                                               &pdf, BSDF_ALL, &flags);
                if (f.IsBlack() || pdf == 0.f) break;
                alpha *= f * AbsDot(wi, pi.shading.n) / pdf;
#ifndef NDEBUG
                Assert(std::isinf(alpha.y()) == false);
#endif
                specularBounce = (flags & BSDF_SPECULAR) != 0;
                ray = pi.SpawnRay(wi);
            }
        }

        // Possibly terminate the path
        if (bounces > 3) {
            Float continueProbability = std::min((Float).5, alpha.y());
            if (sampler.Get1D() > continueProbability) break;
            alpha /= continueProbability;
//.........这里部分代码省略.........
开发者ID:fseraph,项目名称:pbrt-v3,代码行数:101,代码来源:volpath.cpp

示例4: L

rose::Spectrum rose::PathTracerIntegrator::IncomingRadiance(const rose::Ray &ray,
                                                            const rose::RayInterval &interval,
                                                            const rose::Scene &scene,
                                                            uint32_t) const {
    // Final incoming radiance and accumulation value
    Spectrum L(0.f), beta(1.f);
    Ray current_ray(ray);
    RayInterval current_interval(interval);
    bool specular_bounce = false;
    uint32_t bounces;
    // Keep track of specular bounce
    for (bounces = 0;; ++bounces) {
        SurfaceInteraction interaction;
        bool found_interaction = scene.Intersect(current_ray, current_interval, &interaction);

        // Possibly add emission
        if (bounces == 0 || specular_bounce) {
            // Add emitted light
            if (found_interaction) {
                L += beta * interaction.Le(Normalize(-current_ray.Direction()));
            } else {
                for (const auto &light : scene.Lights()) {
                    L += beta * light->Le(current_ray);
                }
            }
        }

        // Terminate path if ray escaped or max depth reached
        if (!found_interaction || bounces >= max_depth) { break; }

        // Compute scattering function
        std::unique_ptr<BSDF> bsdf = interaction.CreateBSDF(true);

        // Get shading variables
        const Vector3f n = interaction.sh_frame.N();
        const Vector3f wo = Normalize(-current_ray.Direction());

        // Loop over all lights and add direct contribution
        for (const auto &light : scene.Lights()) {
            // Sample light
            LightSample light_sample;
            OcclusionTester occlusion_tester;
            Spectrum Li = light->SampleLi(interaction, sampler->Next2D(), &light_sample, &occlusion_tester);
            // Check light return
            if (Li.IsBlack() || light_sample.pdf == 0.f) { continue; }
            // Evaluate BSDF
            Spectrum f = bsdf->F(wo, light_sample.wi);
            if (!f.IsBlack() && occlusion_tester.Unoccluded(scene)) {
                L += beta * f * Li * AbsDotProduct(n, light_sample.wi) / light_sample.pdf;
            }
        }

        // Sample BSDF to get new path
        BXDFSample bsdf_sample;
        Spectrum f = bsdf->SampleF(wo, sampler->Next2D(), &bsdf_sample);
        if (f.IsBlack() || bsdf_sample.pdf == 0.f) { break; }
        // Update beta
        beta *= f * AbsDotProduct(bsdf_sample.wi, n) / bsdf_sample.pdf;
        // Check if bounce is specular
        specular_bounce = (bsdf_sample.sampled_type & SPECULAR) != 0;
        // Compute new ray
        current_ray = interaction.SpawnRay(bsdf_sample.wi);

        // Possibly terminate path with Russian roulette
        if (bounces > 3) {
            float q = std::max(0.05f, 1.f - beta.Norm());
            if (sampler->Next1D() < q) { break; }
            beta /= 1.f - q;
        }
    }

    return L;
}
开发者ID:SRaimondi,项目名称:Rose,代码行数:73,代码来源:path_integrator.cpp

示例5: Li

// PathIntegrator Method Definitions
Spectrum PathIntegrator::Li(const RayDifferential &r, const Scene &scene,
                            Sampler &sampler, MemoryArena &arena) const {
    Spectrum L(0.f);
    // Declare common path integration variables
    RayDifferential ray(r);
    Spectrum pathThroughput = Spectrum(1.f);
    bool specularBounce = false;
    for (int bounces = 0;; ++bounces) {
        // Store intersection into _isect_
        SurfaceInteraction isect;
        bool foundIntersection = scene.Intersect(ray, &isect);

        // Possibly add emitted light and terminate
        if (bounces == 0 || specularBounce) {
            // Add emitted light at path vertex or from the environment
            if (foundIntersection)
                L += pathThroughput * isect.Le(-ray.d);
            else
                for (const auto &light : scene.lights)
                    L += pathThroughput * light->Le(ray);
        }
        if (!foundIntersection || bounces >= maxDepth) break;

        // Compute scattering functions and skip over medium boundaries
        isect.ComputeScatteringFunctions(ray, arena, true);
        if (!isect.bsdf) {
            ray = isect.SpawnRay(ray.d);
            bounces--;
            continue;
        }

        // Sample illumination from lights to find path contribution
        L += pathThroughput *
             UniformSampleOneLight(isect, scene, sampler, arena);

        // Sample BSDF to get new path direction
        Vector3f wo = -ray.d, wi;
        Float pdf;
        BxDFType flags;
        Spectrum f = isect.bsdf->Sample_f(wo, &wi, sampler.Get2D(), &pdf,
                                          BSDF_ALL, &flags);

        if (f.IsBlack() || pdf == 0.f) break;
        pathThroughput *= f * AbsDot(wi, isect.shading.n) / pdf;
#ifndef NDEBUG
        Assert(std::isinf(pathThroughput.y()) == false);
#endif
        specularBounce = (flags & BSDF_SPECULAR) != 0;
        ray = isect.SpawnRay(wi);

        // Account for subsurface scattering, if applicable
        if (isect.bssrdf && (flags & BSDF_TRANSMISSION)) {
            // Importance sample the BSSRDF
            BSSRDFSample bssrdfSample;
            bssrdfSample.uDiscrete = sampler.Get1D();
            bssrdfSample.pos = sampler.Get2D();
            SurfaceInteraction isect_out = isect;
            pathThroughput *= isect.bssrdf->Sample_f(
                isect_out, scene, ray.time, bssrdfSample, arena, &isect, &pdf);
#ifndef NDEBUG
            Assert(std::isinf(pathThroughput.y()) == false);
#endif
            if (pathThroughput.IsBlack()) break;

            // Account for the direct subsurface scattering component
            isect.wo = Vector3f(isect.shading.n);

            // Sample illumination from lights to find path contribution
            L += pathThroughput *
                 UniformSampleOneLight(isect, scene, sampler, arena);

            // Account for the indirect subsurface scattering component
            Spectrum f = isect.bsdf->Sample_f(isect.wo, &wi, sampler.Get2D(),
                                              &pdf, BSDF_ALL, &flags);
            if (f.IsBlack() || pdf == 0.f) break;
            pathThroughput *= f * AbsDot(wi, isect.shading.n) / pdf;
#ifndef NDEBUG
            Assert(std::isinf(pathThroughput.y()) == false);
#endif
            specularBounce = (flags & BSDF_SPECULAR) != 0;
            ray = isect.SpawnRay(wi);
        }

        // Possibly terminate the path
        if (bounces > 3) {
            Float continueProbability = std::min((Float).5, pathThroughput.y());
            if (sampler.Get1D() > continueProbability) break;
            pathThroughput /= continueProbability;
            Assert(std::isinf(pathThroughput.y()) == false);
        }
    }
    return L;
}
开发者ID:RobertoMalatesta,项目名称:pbrt-v3,代码行数:94,代码来源:path.cpp

示例6: Li

Spectrum VolPathIntegrator::Li(const RayDifferential &r, const Scene &scene,
                               Sampler &sampler, MemoryArena &arena,
                               int depth) const {
    ProfilePhase p(Prof::SamplerIntegratorLi);
    Spectrum L(0.f), beta(1.f);
    RayDifferential ray(r);
    bool specularBounce = false;
    int bounces;
    // Added after book publication: etaScale tracks the accumulated effect
    // of radiance scaling due to rays passing through refractive
    // boundaries (see the derivation on p. 527 of the third edition). We
    // track this value in order to remove it from beta when we apply
    // Russian roulette; this is worthwhile, since it lets us sometimes
    // avoid terminating refracted rays that are about to be refracted back
    // out of a medium and thus have their beta value increased.
    Float etaScale = 1;

    for (bounces = 0;; ++bounces) {
        // Intersect _ray_ with scene and store intersection in _isect_
        SurfaceInteraction isect;
        bool foundIntersection = scene.Intersect(ray, &isect);

        // Sample the participating medium, if present
        MediumInteraction mi;
        if (ray.medium) beta *= ray.medium->Sample(ray, sampler, arena, &mi);
        if (beta.IsBlack()) break;

        // Handle an interaction with a medium or a surface
        if (mi.IsValid()) {
            // Terminate path if ray escaped or _maxDepth_ was reached
            if (bounces >= maxDepth) break;

            ++volumeInteractions;
            // Handle scattering at point in medium for volumetric path tracer
            const Distribution1D *lightDistrib =
                lightDistribution->Lookup(mi.p);
            L += beta * UniformSampleOneLight(mi, scene, arena, sampler, true,
                                              lightDistrib);

            Vector3f wo = -ray.d, wi;
            mi.phase->Sample_p(wo, &wi, sampler.Get2D());
            ray = mi.SpawnRay(wi);
        } else {
            ++surfaceInteractions;
            // Handle scattering at point on surface for volumetric path tracer

            // Possibly add emitted light at intersection
            if (bounces == 0 || specularBounce) {
                // Add emitted light at path vertex or from the environment
                if (foundIntersection)
                    L += beta * isect.Le(-ray.d);
                else
                    for (const auto &light : scene.infiniteLights)
                        L += beta * light->Le(ray);
            }

            // Terminate path if ray escaped or _maxDepth_ was reached
            if (!foundIntersection || bounces >= maxDepth) break;

            // Compute scattering functions and skip over medium boundaries
            isect.ComputeScatteringFunctions(ray, arena, true);
            if (!isect.bsdf) {
                ray = isect.SpawnRay(ray.d);
                bounces--;
                continue;
            }

            // Sample illumination from lights to find attenuated path
            // contribution
            const Distribution1D *lightDistrib =
                lightDistribution->Lookup(isect.p);
            L += beta * UniformSampleOneLight(isect, scene, arena, sampler,
                                              true, lightDistrib);

            // Sample BSDF to get new path direction
            Vector3f wo = -ray.d, wi;
            Float pdf;
            BxDFType flags;
            Spectrum f = isect.bsdf->Sample_f(wo, &wi, sampler.Get2D(), &pdf,
                                              BSDF_ALL, &flags);
            if (f.IsBlack() || pdf == 0.f) break;
            beta *= f * AbsDot(wi, isect.shading.n) / pdf;
            DCHECK(std::isinf(beta.y()) == false);
            specularBounce = (flags & BSDF_SPECULAR) != 0;
            if ((flags & BSDF_SPECULAR) && (flags & BSDF_TRANSMISSION)) {
                Float eta = isect.bsdf->eta;
                // Update the term that tracks radiance scaling for refraction
                // depending on whether the ray is entering or leaving the
                // medium.
                etaScale *=
                    (Dot(wo, isect.n) > 0) ? (eta * eta) : 1 / (eta * eta);
            }
            ray = isect.SpawnRay(ray, wi, flags, isect.bsdf->eta);

            // Account for attenuated subsurface scattering, if applicable
            if (isect.bssrdf && (flags & BSDF_TRANSMISSION)) {
                // Importance sample the BSSRDF
                SurfaceInteraction pi;
                Spectrum S = isect.bssrdf->Sample_S(
                    scene, sampler.Get1D(), sampler.Get2D(), arena, &pi, &pdf);
//.........这里部分代码省略.........
开发者ID:dbadb,项目名称:pbrt-v3,代码行数:101,代码来源:volpath.cpp

示例7: Li

// PathIntegrator Method Definitions
Spectrum PathIntegrator::Li(const RayDifferential &r, const Scene &scene,
                            Sampler &sampler, MemoryArena &arena,
                            int depth) const {
    ProfilePhase p(Prof::SamplerIntegratorLi);
    Spectrum L(0.f), beta(1.f);
    RayDifferential ray(r);
    bool specularBounce = false;
    for (int bounces = 0;; ++bounces) {
        // Find next path vertex and accumulate contribution

        // Intersect _ray_ with scene and store intersection in _isect_
        SurfaceInteraction isect;
        bool foundIntersection = scene.Intersect(ray, &isect);

        // Possibly add emitted light at intersection
        if (bounces == 0 || specularBounce) {
            // Add emitted light at path vertex or from the environment
            if (foundIntersection)
                L += beta * isect.Le(-ray.d);
            else
                for (const auto &light : scene.lights)
                    L += beta * light->Le(ray);
        }

        // Terminate path if ray escaped or _maxDepth_ was reached
        if (!foundIntersection || bounces >= maxDepth) break;

        // Compute scattering functions and skip over medium boundaries
        isect.ComputeScatteringFunctions(ray, arena, true);
        if (!isect.bsdf) {
            ray = isect.SpawnRay(ray.d);
            bounces--;
            continue;
        }

        // Sample illumination from lights to find path contribution
        L += beta * UniformSampleOneLight(isect, scene, arena, sampler);

        // Sample BSDF to get new path direction
        Vector3f wo = -ray.d, wi;
        Float pdf;
        BxDFType flags;
        Spectrum f = isect.bsdf->Sample_f(wo, &wi, sampler.Get2D(), &pdf,
                                          BSDF_ALL, &flags);
        if (f.IsBlack() || pdf == 0.f) break;
        beta *= f * AbsDot(wi, isect.shading.n) / pdf;
        Assert(std::isinf(beta.y()) == false);
        specularBounce = (flags & BSDF_SPECULAR) != 0;
        ray = isect.SpawnRay(wi);

        // Account for subsurface scattering, if applicable
        if (isect.bssrdf && (flags & BSDF_TRANSMISSION)) {
            // Importance sample the BSSRDF
            SurfaceInteraction pi;
            Spectrum S = isect.bssrdf->Sample_S(
                scene, sampler.Get1D(), sampler.Get2D(), arena, &pi, &pdf);
#ifndef NDEBUG
            Assert(std::isinf(beta.y()) == false);
#endif
            if (S.IsBlack() || pdf == 0) break;
            beta *= S / pdf;

            // Account for the direct subsurface scattering component
            L += beta * UniformSampleOneLight(pi, scene, arena, sampler);

            // Account for the indirect subsurface scattering component
            Spectrum f = pi.bsdf->Sample_f(pi.wo, &wi, sampler.Get2D(), &pdf,
                                           BSDF_ALL, &flags);
            if (f.IsBlack() || pdf == 0) break;
            beta *= f * AbsDot(wi, pi.shading.n) / pdf;
#ifndef NDEBUG
            Assert(std::isinf(beta.y()) == false);
#endif
            specularBounce = (flags & BSDF_SPECULAR) != 0;
            ray = pi.SpawnRay(wi);
        }

        // Possibly terminate the path with Russian roulette
        if (bounces > 3) {
            Float continueProbability = std::min((Float).95, beta.y());
            if (sampler.Get1D() > continueProbability) break;
            beta /= continueProbability;
            Assert(std::isinf(beta.y()) == false);
        }
    }
    return L;
}
开发者ID:Twinklebear,项目名称:pbrt-v3,代码行数:88,代码来源:path.cpp

示例8: EstimateDirect

Spectrum EstimateDirect(const Interaction &it, const Point2f &uScattering,
                        const Light &light, const Point2f &uLight,
                        const Scene &scene, Sampler &sampler,
                        MemoryArena &arena, bool handleMedia, bool specular) {
    BxDFType bsdfFlags =
        specular ? BSDF_ALL : BxDFType(BSDF_ALL & ~BSDF_SPECULAR);
    Spectrum Ld(0.f);
    // Sample light source with multiple importance sampling
    Vector3f wi;
    Float lightPdf = 0, scatteringPdf = 0;
    VisibilityTester visibility;
    Spectrum Li = light.Sample_Li(it, uLight, &wi, &lightPdf, &visibility);
    if (lightPdf > 0 && !Li.IsBlack()) {
        // Compute BSDF or phase function's value for light sample
        Spectrum f;
        if (it.IsSurfaceInteraction()) {
            // Evaluate BSDF for light sampling strategy
            const SurfaceInteraction &isect = (const SurfaceInteraction &)it;
            f = isect.bsdf->f(isect.wo, wi, bsdfFlags) *
                AbsDot(wi, isect.shading.n);
            scatteringPdf = isect.bsdf->Pdf(isect.wo, wi, bsdfFlags);
        } else {
            // Evaluate phase function for light sampling strategy
            const MediumInteraction &mi = (const MediumInteraction &)it;
            Float p = mi.phase->p(mi.wo, wi);
            f = Spectrum(p);
            scatteringPdf = p;
        }
        if (!f.IsBlack()) {
            // Compute effect of visibility for light source sample
            if (handleMedia)
                Li *= visibility.Tr(scene, sampler);
            else if (!visibility.Unoccluded(scene))
                Li = Spectrum(0.f);

            // Add light's contribution to reflected radiance
            if (!Li.IsBlack()) {
                if (IsDeltaLight(light.flags))
                    Ld += f * Li / lightPdf;
                else {
                    Float weight =
                        PowerHeuristic(1, lightPdf, 1, scatteringPdf);
                    Ld += f * Li * weight / lightPdf;
                }
            }
        }
    }

    // Sample BSDF with multiple importance sampling
    if (!IsDeltaLight(light.flags)) {
        Spectrum f;
        bool sampledSpecular = false;
        if (it.IsSurfaceInteraction()) {
            // Sample scattered direction for surface interactions
            BxDFType sampledType;
            const SurfaceInteraction &isect = (const SurfaceInteraction &)it;
            f = isect.bsdf->Sample_f(isect.wo, &wi, uScattering, &scatteringPdf,
                                     bsdfFlags, &sampledType);
            f *= AbsDot(wi, isect.shading.n);
            sampledSpecular = sampledType & BSDF_SPECULAR;
        } else {
            // Sample scattered direction for medium interactions
            const MediumInteraction &mi = (const MediumInteraction &)it;
            Float p = mi.phase->Sample_p(mi.wo, &wi, uScattering);
            f = Spectrum(p);
            scatteringPdf = p;
        }
        if (!f.IsBlack() && scatteringPdf > 0) {
            // Account for light contributions along sampled direction _wi_
            Float weight = 1;
            if (!sampledSpecular) {
                lightPdf = light.Pdf_Li(it, wi);
                if (lightPdf == 0) return Ld;
                weight = PowerHeuristic(1, scatteringPdf, 1, lightPdf);
            }

            // Find intersection and compute transmittance
            SurfaceInteraction lightIsect;
            Ray ray = it.SpawnRay(wi);
            Spectrum Tr(1.f);
            bool foundSurfaceInteraction =
                handleMedia ? scene.IntersectTr(ray, sampler, &lightIsect, &Tr)
                            : scene.Intersect(ray, &lightIsect);

            // Add light contribution from material sampling
            Spectrum Li(0.f);
            if (foundSurfaceInteraction) {
                if (lightIsect.primitive->GetAreaLight() == &light)
                    Li = lightIsect.Le(-wi);
            } else
                Li = light.Le(ray);
            if (!Li.IsBlack()) Ld += f * Li * Tr * weight / scatteringPdf;
        }
    }
    return Ld;
}
开发者ID:DINKIN,项目名称:pbrt-v3,代码行数:96,代码来源:integrator.cpp

示例9: Li

Spectrum PathIntegrator::Li(const RayDifferential &r, const Scene &scene,
                            Sampler &sampler, MemoryArena &arena,
                            int depth) const {
    ProfilePhase p(Prof::SamplerIntegratorLi);
    Spectrum L(0.f), beta(1.f);
    RayDifferential ray(r);
    bool specularBounce = false;
    int bounces;
    for (bounces = 0;; ++bounces) {
        // Find next path vertex and accumulate contribution
        VLOG(2) << "Path tracer bounce " << bounces << ", current L = " << L <<
            ", beta = " << beta;

        // Intersect _ray_ with scene and store intersection in _isect_
        SurfaceInteraction isect;
        bool foundIntersection = scene.Intersect(ray, &isect);

        // Possibly add emitted light at intersection
        if (bounces == 0 || specularBounce) {
            // Add emitted light at path vertex or from the environment
            if (foundIntersection) {
                L += beta * isect.Le(-ray.d);
                VLOG(2) << "Added Le -> L = " << L;
            } else {
                for (const auto &light : scene.infiniteLights)
                    L += beta * light->Le(ray);
                VLOG(2) << "Added infinite area lights -> L = " << L;
            }
        }

        // Terminate path if ray escaped or _maxDepth_ was reached
        if (!foundIntersection || bounces >= maxDepth) break;

        // Compute scattering functions and skip over medium boundaries
        isect.ComputeScatteringFunctions(ray, arena, true);
        if (!isect.bsdf) {
            VLOG(2) << "Skipping intersection due to null bsdf";
            ray = isect.SpawnRay(ray.d);
            bounces--;
            continue;
        }

        const Distribution1D *distrib = lightDistribution->Lookup(isect.p);

        // Sample illumination from lights to find path contribution.
        // (But skip this for perfectly specular BSDFs.)
        if (isect.bsdf->NumComponents(BxDFType(BSDF_ALL & ~BSDF_SPECULAR)) >
            0) {
            ++totalPaths;
            Spectrum Ld =
                beta * UniformSampleOneLight(isect, scene, arena, sampler, false,
                                             distrib);
            VLOG(2) << "Sampled direct lighting Ld = " << Ld;
            if (Ld.IsBlack()) ++zeroRadiancePaths;
            CHECK_GE(Ld.y(), 0.f);
            L += Ld;
        }

        // Sample BSDF to get new path direction
        Vector3f wo = -ray.d, wi;
        Float pdf;
        BxDFType flags;
        Spectrum f = isect.bsdf->Sample_f(wo, &wi, sampler.Get2D(), &pdf,
                                          BSDF_ALL, &flags);
        VLOG(2) << "Sampled BSDF, f = " << f << ", pdf = " << pdf;
        if (f.IsBlack() || pdf == 0.f) break;
        beta *= f * AbsDot(wi, isect.shading.n) / pdf;
        VLOG(2) << "Updated beta = " << beta;
        CHECK_GE(beta.y(), 0.f);
        DCHECK(!std::isinf(beta.y()));
        specularBounce = (flags & BSDF_SPECULAR) != 0;
        ray = isect.SpawnRay(wi);

        // Account for subsurface scattering, if applicable
        if (isect.bssrdf && (flags & BSDF_TRANSMISSION)) {
            // Importance sample the BSSRDF
            SurfaceInteraction pi;
            Spectrum S = isect.bssrdf->Sample_S(
                scene, sampler.Get1D(), sampler.Get2D(), arena, &pi, &pdf);
            DCHECK(!std::isinf(beta.y()));
            if (S.IsBlack() || pdf == 0) break;
            beta *= S / pdf;

            // Account for the direct subsurface scattering component
            L += beta * UniformSampleOneLight(pi, scene, arena, sampler, false,
                                              lightDistribution->Lookup(pi.p));

            // Account for the indirect subsurface scattering component
            Spectrum f = pi.bsdf->Sample_f(pi.wo, &wi, sampler.Get2D(), &pdf,
                                           BSDF_ALL, &flags);
            if (f.IsBlack() || pdf == 0) break;
            beta *= f * AbsDot(wi, pi.shading.n) / pdf;
            DCHECK(!std::isinf(beta.y()));
            specularBounce = (flags & BSDF_SPECULAR) != 0;
            ray = pi.SpawnRay(wi);
        }

        // Possibly terminate the path with Russian roulette
        if (beta.y() < rrThreshold && bounces > 3) {
            Float q = std::max((Float).05, 1 - beta.MaxComponentValue());
//.........这里部分代码省略.........
开发者ID:syoyo,项目名称:pbrt-v3,代码行数:101,代码来源:path.cpp


注:本文中的SurfaceInteraction::Le方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。