From 97152416de093ea08cc2ab13e7867c9172f5f410 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Thu, 12 Nov 2020 13:24:27 -0800 Subject: [PATCH] Update from book source. No meaningful changes to functionality. --- src/pbrt/cpu/integrators.cpp | 107 +++++++++++++----------------- src/pbrt/cpu/integrators.h | 12 ++-- src/pbrt/cpu/integrators_test.cpp | 2 +- src/pbrt/media.h | 2 +- 4 files changed, 53 insertions(+), 70 deletions(-) diff --git a/src/pbrt/cpu/integrators.cpp b/src/pbrt/cpu/integrators.cpp index 0195358..6fd6222 100644 --- a/src/pbrt/cpu/integrators.cpp +++ b/src/pbrt/cpu/integrators.cpp @@ -1550,13 +1550,10 @@ struct EndpointInteraction : Interaction { "Expect both union members have same size"); } - EndpointInteraction(LightHandle light, const Ray &r, const Interaction &intr) + EndpointInteraction(LightHandle light, const Interaction &intr) : Interaction(intr), light(light) {} EndpointInteraction(LightHandle light, const Ray &r) : Interaction(r.o, r.time, r.medium), light(light) {} - - EndpointInteraction(const Interaction &it, LightHandle light) - : Interaction(it), light(light) {} EndpointInteraction(const Ray &ray) : Interaction(ray(1), Normal3f(-ray.d), ray.time, ray.medium), light(nullptr) {} }; @@ -1596,13 +1593,14 @@ struct Vertex { const SampledSpectrum &beta); static inline Vertex CreateCamera(CameraHandle camera, const Interaction &it, const SampledSpectrum &beta); + static inline Vertex CreateLight(LightHandle light, const Ray &ray, const SampledSpectrum &Le, Float pdf); - static inline Vertex CreateLight(LightHandle light, const Ray &ray, - const Interaction &intr, const SampledSpectrum &Le, - Float pdf); + static inline Vertex CreateLight(LightHandle light, const Interaction &intr, + const SampledSpectrum &Le, Float pdf); static inline Vertex CreateLight(const EndpointInteraction &ei, const SampledSpectrum &beta, Float pdf); + static inline Vertex CreateMedium(const MediumInteraction &mi, const SampledSpectrum &beta, Float pdf, const Vertex &prev); @@ -1697,10 +1695,10 @@ struct Vertex { Le += light.Le(Ray(p(), -w), lambda); return Le; - } else { - return si.areaLight ? si.areaLight.L(si.p(), si.n, si.uv, w, lambda) - : SampledSpectrum(0.); - } + } else if (si.areaLight) + return si.areaLight.L(si.p(), si.n, si.uv, w, lambda); + else + return SampledSpectrum(0.f); } std::string ToString() const { @@ -1756,7 +1754,7 @@ struct Vertex { Float PDF(const Integrator &integrator, const Vertex *prev, const Vertex &next) const { if (type == VertexType::Light) - return PdfLight(integrator, next); + return PDFLight(integrator, next); // Compute directions to preceding and next vertex Vector3f wn = next.p() - p(); if (LengthSquared(wn) == 0) @@ -1786,10 +1784,11 @@ struct Vertex { return ConvertDensity(pdf, next); } - Float PdfLight(const Integrator &integrator, const Vertex &v) const { + Float PDFLight(const Integrator &integrator, const Vertex &v) const { Vector3f w = v.p() - p(); Float invDist2 = 1 / LengthSquared(w); w *= std::sqrt(invDist2); + // Compute sampling density _pdf_ for light type Float pdf; if (IsInfiniteLight()) { // Compute planar sampling density for infinite light sources @@ -1809,22 +1808,20 @@ struct Vertex { pdf = pdfDir * invDist2; } else { - // Get pointer _light_ to the light source at the vertex + // Compute sampling density for non-infinite light sources CHECK(type == VertexType::Light); CHECK(ei.light != nullptr); - LightHandle light = ei.light; - - // Compute sampling density for non-infinite light sources Float pdfPos, pdfDir; - light.PDF_Le(Ray(p(), w, time()), &pdfPos, &pdfDir); + ei.light.PDF_Le(Ray(p(), w, time()), &pdfPos, &pdfDir); pdf = pdfDir * invDist2; } + if (v.IsOnSurface()) pdf *= AbsDot(v.ng(), w); return pdf; } - Float PdfLightOrigin(const std::vector &infiniteLights, const Vertex &v, + Float PDFLightOrigin(const std::vector &infiniteLights, const Vertex &v, LightSamplerHandle lightSampler) { Vector3f w = v.p() - p(); if (LengthSquared(w) == 0) @@ -1834,25 +1831,14 @@ struct Vertex { // Return solid angle density for infinite light sources return InfiniteLightDensity(infiniteLights, lightSampler, w); - } else if (IsOnSurface()) { - // Return probability for emissive surface - if (type == VertexType::Light) - CHECK(ei.light.Is()); // since that's all we've - // got currently... - LightHandle light = (type == VertexType::Light) ? ei.light : si.areaLight; - Float pdfChoice = lightSampler.PDF(light); - Float pdfPos, pdfDir; - light.PDF_Le(ei, w, &pdfPos, &pdfDir); - return pdfPos * pdfChoice; - } else { - // Return solid angle density for non-infinite light sources - Float pdfPos, pdfDir; - CHECK(IsLight()); - LightHandle light = type == VertexType::Light ? ei.light : si.areaLight; - CHECK(light != nullptr); - Float pdfChoice = lightSampler.PDF(light); - light.PDF_Le(Ray(p(), w, time()), &pdfPos, &pdfDir); + // Return solid angle density for non-infinite light source + LightHandle light = (type == VertexType::Light) ? ei.light : si.areaLight; + Float pdfPos, pdfDir, pdfChoice = lightSampler.PDF(light); + if (IsOnSurface()) + light.PDF_Le(ei, w, &pdfPos, &pdfDir); + else + light.PDF_Le(Ray(p(), w, time()), &pdfPos, &pdfDir); return pdfPos * pdfChoice; } } @@ -1876,10 +1862,9 @@ inline Vertex Vertex::CreateLight(LightHandle light, const Ray &ray, return v; } -inline Vertex Vertex::CreateLight(LightHandle light, const Ray &ray, - const Interaction &intr, const SampledSpectrum &Le, - Float pdf) { - Vertex v(VertexType::Light, EndpointInteraction(light, ray, intr), Le); +inline Vertex Vertex::CreateLight(LightHandle light, const Interaction &intr, + const SampledSpectrum &Le, Float pdf) { + Vertex v(VertexType::Light, EndpointInteraction(light, intr), Le); v.pdfFwd = pdf; return v; } @@ -1934,26 +1919,30 @@ int GenerateLightSubpath(const Integrator &integrator, SampledWavelengths &lambd SamplerHandle sampler, CameraHandle camera, ScratchBuffer &scratchBuffer, int maxDepth, Float time, LightSamplerHandle lightSampler, Vertex *path, bool regularize) { + // Generate light subpath and initialize _path_ vertices if (maxDepth == 0) return 0; - // Sample initial ray for light subpath + // Sample light for BDPT light subpath pstd::optional sampledLight = lightSampler.Sample(sampler.Get1D()); if (!sampledLight) return 0; LightHandle light = sampledLight->light; - Float lightPDF = sampledLight->pdf; + Float lightSamplePDF = sampledLight->pdf; + + // Sample initial ray for light subpath pstd::optional les = light.SampleLe(sampler.Get2D(), sampler.Get2D(), lambda, time); if (!les || les->pdfPos == 0 || les->pdfDir == 0 || !les->L) return 0; RayDifferential ray(les->ray); - // Generate first vertex on light subpath and start random walk - path[0] = les->intr ? Vertex::CreateLight(light, ray, *les->intr, les->L, - les->pdfPos * lightPDF) - : Vertex::CreateLight(light, ray, les->L, les->pdfPos * lightPDF); - SampledSpectrum beta = - les->L * les->AbsCosTheta(ray.d) / (lightPDF * les->pdfPos * les->pdfDir); + // Generate first vertex of light subpath + Float lightPDF = lightSamplePDF * les->pdfPos; + path[0] = les->intr ? Vertex::CreateLight(light, *les->intr, les->L, lightPDF) + : Vertex::CreateLight(light, ray, les->L, lightPDF); + + // Follow light subpath start random walk + SampledSpectrum beta = les->L * les->AbsCosTheta(ray.d) / (lightPDF * les->pdfDir); PBRT_DBG("%s\n", StringPrintf( "Starting light subpath. Ray: %s, Le %s, beta %s, pdfPos %f, pdfDir %f", @@ -2171,14 +2160,14 @@ Float MISWeight(const Integrator &integrator, Vertex *lightVertices, ScopedAssignment a4; if (pt) a4 = {&pt->pdfRev, s > 0 ? qs->PDF(integrator, qsMinus, *pt) - : pt->PdfLightOrigin(integrator.infiniteLights, *ptMinus, + : pt->PDFLightOrigin(integrator.infiniteLights, *ptMinus, lightSampler)}; // Update reverse density of vertex $\pt{}_{t-2}$ ScopedAssignment a5; if (ptMinus) a5 = {&ptMinus->pdfRev, s > 0 ? pt->PDF(integrator, qs, *ptMinus) - : pt->PdfLight(integrator, *ptMinus)}; + : pt->PDFLight(integrator, *ptMinus)}; // Update reverse density of vertices $\pq{}_{s-1}$ and $\pq{}_{s-2}$ ScopedAssignment a6; @@ -2259,7 +2248,7 @@ void BDPTIntegrator::Render() { SampledSpectrum BDPTIntegrator::Li(RayDifferential ray, SampledWavelengths &lambda, SamplerHandle sampler, ScratchBuffer &scratchBuffer, - VisibleSurface *visibleSurface) const { + VisibleSurface *) const { // Trace the camera and light subpaths Vertex *cameraVertices = scratchBuffer.Alloc(maxDepth + 2); int nCamera = GenerateCameraSubpath(*this, ray, lambda, sampler, scratchBuffer, @@ -2368,10 +2357,10 @@ SampledSpectrum ConnectBDPT(const Integrator &integrator, SampledWavelengths &la pstd::optional lightWeight = light.SampleLi(ctx, sampler.Get2D(), lambda); if (lightWeight) { - EndpointInteraction ei(lightWeight->pLight, light); + EndpointInteraction ei(light, lightWeight->pLight); sampled = Vertex::CreateLight( ei, lightWeight->L / (lightWeight->pdf * lightPDF), 0); - sampled.pdfFwd = sampled.PdfLightOrigin(integrator.infiniteLights, pt, + sampled.pdfFwd = sampled.PDFLightOrigin(integrator.infiniteLights, pt, lightSampler); L = pt.beta * pt.f(sampled, TransportMode::Radiance) * sampled.beta; if (pt.IsOnSurface()) @@ -2425,10 +2414,9 @@ SampledSpectrum ConnectBDPT(const Integrator &integrator, SampledWavelengths &la std::string BDPTIntegrator::ToString() const { return StringPrintf("[ BDPTIntegrator maxDepth: %d visualizeStrategies: %s " - "visualizeWeights: %s lightSampleStrategy: %s regularize: %s " - "lightSampler: %s ]", - maxDepth, visualizeStrategies, visualizeWeights, - lightSampleStrategy, regularize, lightSampler); + "visualizeWeights: %s regularize: %s lightSampler: %s ]", + maxDepth, visualizeStrategies, visualizeWeights, regularize, + lightSampler); } std::unique_ptr BDPTIntegrator::Create( @@ -2444,11 +2432,10 @@ std::unique_ptr BDPTIntegrator::Create( maxDepth = 5; } - std::string lightStrategy = parameters.GetOneString("lightsampler", "power"); bool regularize = parameters.GetOneBool("regularize", false); return std::make_unique(camera, sampler, aggregate, lights, maxDepth, visualizeStrategies, visualizeWeights, - lightStrategy, regularize); + regularize); } STAT_PERCENT("Integrator/Acceptance rate", acceptedMutations, totalMutations); diff --git a/src/pbrt/cpu/integrators.h b/src/pbrt/cpu/integrators.h index 482d1e1..1316297 100644 --- a/src/pbrt/cpu/integrators.h +++ b/src/pbrt/cpu/integrators.h @@ -337,15 +337,13 @@ class BDPTIntegrator : public RayIntegrator { BDPTIntegrator(CameraHandle camera, SamplerHandle sampler, PrimitiveHandle aggregate, std::vector lights, int maxDepth, bool visualizeStrategies, bool visualizeWeights, - const std::string &lightSampleStrategy = "power", bool regularize = false) : RayIntegrator(camera, sampler, aggregate, lights), maxDepth(maxDepth), - visualizeStrategies(visualizeStrategies), - visualizeWeights(visualizeWeights), - lightSampleStrategy(lightSampleStrategy), + regularize(regularize), lightSampler(new PowerLightSampler(lights, Allocator())), - regularize(regularize) {} + visualizeStrategies(visualizeStrategies), + visualizeWeights(visualizeWeights) {} SampledSpectrum Li(RayDifferential ray, SampledWavelengths &lambda, SamplerHandle sampler, ScratchBuffer &scratchBuffer, @@ -362,11 +360,9 @@ class BDPTIntegrator : public RayIntegrator { private: // BDPTIntegrator Private Members int maxDepth; - bool visualizeStrategies; - bool visualizeWeights; - std::string lightSampleStrategy; bool regularize; LightSamplerHandle lightSampler; + bool visualizeStrategies, visualizeWeights; mutable std::vector weightFilms; }; diff --git a/src/pbrt/cpu/integrators_test.cpp b/src/pbrt/cpu/integrators_test.cpp index d5cc19c..fd12ab9 100644 --- a/src/pbrt/cpu/integrators_test.cpp +++ b/src/pbrt/cpu/integrators_test.cpp @@ -376,7 +376,7 @@ std::vector GetIntegrators() { Integrator *integrator = new BDPTIntegrator(camera, sampler.first, scene.aggregate, scene.lights, - 6, false, false, "power", false); + 6, false, false, false); integrators.push_back({integrator, filmp, "BDPT, depth 8, Perspective, " + sampler.second + ", " + scene.description, diff --git a/src/pbrt/media.h b/src/pbrt/media.h index cfbce98..dea28c4 100644 --- a/src/pbrt/media.h +++ b/src/pbrt/media.h @@ -374,7 +374,7 @@ class UniformGridMediumProvider { pstd::vector GetMaxDensityGrid(Allocator alloc, Point3i *res) const { // Set _gridResolution_ and allocate _maxGrid_ - *res = Point3i(4, 4, 4); + *res = Point3i(16, 16, 16); pstd::vector maxGrid(alloc); maxGrid.resize(res->x * res->y * res->z); -- GitLab