diff --git a/src/pbrt/cameras.h b/src/pbrt/cameras.h index 4a15e6ff005883a9b5f26388e406b75141562ecd..676d888ad90d0b805ee71c1ef388a6e6699990d0 100644 --- a/src/pbrt/cameras.h +++ b/src/pbrt/cameras.h @@ -156,11 +156,10 @@ class CameraBase { Vector3f *dpdx, Vector3f *dpdy) const { // Compute tangent plane equation for ray differential intersections Point3f pCamera = CameraFromRender(p, time); - Normal3f nCamera = CameraFromRender(n, time); Transform DownZFromCamera = RotateFromTo(Normalize(Vector3f(pCamera)), Vector3f(0, 0, 1)); Point3f pDownZ = DownZFromCamera(pCamera); - Normal3f nDownZ = DownZFromCamera(nCamera); + Normal3f nDownZ = DownZFromCamera(CameraFromRender(n, time)); Float d = Dot(nDownZ, Vector3f(pDownZ)); // Find intersection points for approximated camera differential rays diff --git a/src/pbrt/interaction.cpp b/src/pbrt/interaction.cpp index 25c38088595a077509c022da524c0f9071d5dbfc..5025bc44db422c6fd39312167066ad33340e34ac 100644 --- a/src/pbrt/interaction.cpp +++ b/src/pbrt/interaction.cpp @@ -42,7 +42,7 @@ void SurfaceInteraction::ComputeDifferentials(const RayDifferential &ray, Camera int samplesPerPixel) { if (ray.hasDifferentials && Dot(n, ray.rxDirection) != 0 && Dot(n, ray.ryDirection) != 0) { - // Estimate screen-space change in $\pt{}$ + // Estimate screen-space change in $\pt{}$ using ray differentials // Compute auxiliary intersection points with plane, _px_ and _py_ Float d = -Dot(n, Vector3f(p())); Float tx = (-Dot(n, Vector3f(ray.rxOrigin)) - d) / Dot(n, ray.rxDirection); @@ -55,24 +55,28 @@ void SurfaceInteraction::ComputeDifferentials(const RayDifferential &ray, Camera dpdx = px - p(); dpdy = py - p(); - } else + } else { + // Approximate screen-space change in $\pt{}$ based on camera projection camera.Approximate_dp_dxy(p(), n, time, samplesPerPixel, &dpdx, &dpdy); + } // Estimate screen-space change in $(u,v)$ - Float a00 = Dot(dpdu, dpdu), a01 = Dot(dpdu, dpdv), a11 = Dot(dpdv, dpdv); - Float invDet = 1 / (DifferenceOfProducts(a00, a11, a01, a01)); - - Float b0x = Dot(dpdu, dpdx), b1x = Dot(dpdv, dpdx); - Float b0y = Dot(dpdu, dpdy), b1y = Dot(dpdv, dpdy); - - /* Set the UV partials to zero if dpdu and/or dpdv == 0 */ + // Compute $\transpose{\XFORM{A}} \XFORM{A}$ and its determinant + Float ata00 = Dot(dpdu, dpdu), ata01 = Dot(dpdu, dpdv); + Float ata11 = Dot(dpdv, dpdv); + Float invDet = 1 / (DifferenceOfProducts(ata00, ata11, ata01, ata01)); invDet = IsFinite(invDet) ? invDet : 0.f; - dudx = DifferenceOfProducts(a11, b0x, a01, b1x) * invDet; - dvdx = DifferenceOfProducts(a00, b1x, a01, b0x) * invDet; + // Compute $\transpose{\XFORM{A}} \VEC{b}$ for $x$ and $y$ + Float atb0x = Dot(dpdu, dpdx), atb1x = Dot(dpdv, dpdx); + Float atb0y = Dot(dpdu, dpdy), atb1y = Dot(dpdv, dpdy); - dudy = DifferenceOfProducts(a11, b0y, a01, b1y) * invDet; - dvdy = DifferenceOfProducts(a00, b1y, a01, b0y) * invDet; + // Compute $u$ and $v$ partial derivatives with respect to $x$ and $y$ + dudx = DifferenceOfProducts(ata11, atb0x, ata01, atb1x) * invDet; + dvdx = DifferenceOfProducts(ata00, atb1x, ata01, atb0x) * invDet; + dudy = DifferenceOfProducts(ata11, atb0y, ata01, atb1y) * invDet; + dvdy = DifferenceOfProducts(ata00, atb1y, ata01, atb0y) * invDet; + // Clamp partial derivatives of $u$ and $v$ to reasonable values dudx = IsFinite(dudx) ? Clamp(dudx, -1e8f, 1e8f) : 0.f; dvdx = IsFinite(dvdx) ? Clamp(dvdx, -1e8f, 1e8f) : 0.f; dudy = IsFinite(dudy) ? Clamp(dudy, -1e8f, 1e8f) : 0.f; @@ -106,12 +110,12 @@ RayDifferential SurfaceInteraction::SpawnRay(const RayDifferential &rayi, rd.ryOrigin = p() + dpdy; // Compute differential reflected directions - Float dwoDotNdx = Dot(dwodx, ns) + Dot(wo, dndx); - Float dwoDotNdy = Dot(dwody, ns) + Dot(wo, dndy); + Float dwoDotn_dx = Dot(dwodx, ns) + Dot(wo, dndx); + Float dwoDotn_dy = Dot(dwody, ns) + Dot(wo, dndy); rd.rxDirection = - wi - dwodx + 2 * Vector3f(Dot(wo, ns) * dndx + dwoDotNdx * ns); + wi - dwodx + 2 * Vector3f(Dot(wo, ns) * dndx + dwoDotn_dx * ns); rd.ryDirection = - wi - dwody + 2 * Vector3f(Dot(wo, ns) * dndy + dwoDotNdy * ns); + wi - dwody + 2 * Vector3f(Dot(wo, ns) * dndy + dwoDotn_dy * ns); } else if (flags == BxDFFlags::SpecularTransmission) { // Initialize origins of specular differential rays diff --git a/src/pbrt/scene.cpp b/src/pbrt/scene.cpp index 694421ab2915e4735e43c776524e9499ac6be161..7f7ede822ca8ea4c494ab240865884f6f94885ef 100644 --- a/src/pbrt/scene.cpp +++ b/src/pbrt/scene.cpp @@ -686,7 +686,7 @@ void BasicSceneBuilder::AreaLightSource(const std::string &name, void BasicScene::SetOptions(SceneEntity filter, SceneEntity film, CameraSceneEntity camera, SceneEntity sampler, SceneEntity integ, SceneEntity accel) { - // Store information for specificed integrator and accelerator + // Store information for specified integrator and accelerator filmColorSpace = film.parameters.ColorSpace(); integrator = integ; accelerator = accel; @@ -767,7 +767,7 @@ Medium BasicScene::GetMedium(const std::string &name, const FileLoc *loc) { Medium m = iter->second; mediaMutex.unlock(); return m; - } else { + } else { auto fiter = mediumFutures.find(name); if (fiter == mediumFutures.end()) ErrorExit(loc, "%s: medium is not defined.", name); @@ -795,11 +795,10 @@ std::map BasicScene::CreateMedia() { mediaMap[m.first] = *med; } } + LOG_VERBOSE("Consume media futures finished"); + mediumFutures.clear(); } - mediumFutures.clear(); mediaMutex.unlock(); - LOG_VERBOSE("Consume media futures finished"); - return mediaMap; } diff --git a/src/pbrt/util/parallel.h b/src/pbrt/util/parallel.h index 5c491d1283712f301f3ac6c347462cf3c7032d73..be62398c86b8fd715772c788aae1828cc00c02a5 100644 --- a/src/pbrt/util/parallel.h +++ b/src/pbrt/util/parallel.h @@ -362,6 +362,7 @@ class Future { Wait(); return fut.get(); } + pstd::optional TryGet(std::mutex *mutex) { if (IsReady()) return Get(); diff --git a/src/pbrt/util/pstd.cpp b/src/pbrt/util/pstd.cpp index 893575330d4b690803ec4bc1699dbf47278043d7..3e91bc847d1d4505a329eb73b6f1ae1ca102d8a0 100644 --- a/src/pbrt/util/pstd.cpp +++ b/src/pbrt/util/pstd.cpp @@ -75,6 +75,7 @@ void *monotonic_buffer_resource::do_allocate(size_t bytes, size_t align) { // so this is tied to pbrt's current usage of them... CHECK(constructTID == std::this_thread::get_id()); #endif + if (bytes > block_size) // We've got a big allocation; let the current block be so that // smaller allocations have a chance at using up more of it. diff --git a/src/pbrt/wavefront/integrator.cpp b/src/pbrt/wavefront/integrator.cpp index dbbe3e5077766c197585ba70ed052ae9a177c4a8..69e4ee2cd6fda58d7bf2fc6b4e1446b59b860fa9 100644 --- a/src/pbrt/wavefront/integrator.cpp +++ b/src/pbrt/wavefront/integrator.cpp @@ -79,9 +79,8 @@ static void updateMaterialNeeds( WavefrontPathIntegrator::WavefrontPathIntegrator( pstd::pmr::memory_resource *memoryResource, BasicScene &scene) : memoryResource(memoryResource) { - ThreadLocal threadAllocators([memoryResource]() { - return Allocator(memoryResource); - }); + ThreadLocal threadAllocators( + [memoryResource]() { return Allocator(memoryResource); }); Allocator alloc = threadAllocators.Get(); diff --git a/src/pbrt/wavefront/surfscatter.cpp b/src/pbrt/wavefront/surfscatter.cpp index 487f257d0a144882877a6ce09e5e24ec070b5756..74dd45a34b19e8a288029ac5c6359026c3847c9c 100644 --- a/src/pbrt/wavefront/surfscatter.cpp +++ b/src/pbrt/wavefront/surfscatter.cpp @@ -72,21 +72,23 @@ void WavefrontPathIntegrator::EvaluateMaterialAndBSDF(MaterialEvalQueue *evalQue &dpdy); Vector3f dpdu = w.dpdu, dpdv = w.dpdv; // Estimate screen-space change in $(u,v)$ - Float a00 = Dot(dpdu, dpdu), a01 = Dot(dpdu, dpdv), a11 = Dot(dpdv, dpdv); - Float invDet = 1 / (DifferenceOfProducts(a00, a11, a01, a01)); - - Float b0x = Dot(dpdu, dpdx), b1x = Dot(dpdv, dpdx); - Float b0y = Dot(dpdu, dpdy), b1y = Dot(dpdv, dpdy); - - /* Set the UV partials to zero if dpdu and/or dpdv == 0 */ + // Compute $\transpose{\XFORM{A}} \XFORM{A}$ and its determinant + Float ata00 = Dot(dpdu, dpdu), ata01 = Dot(dpdu, dpdv); + Float ata11 = Dot(dpdv, dpdv); + Float invDet = 1 / (DifferenceOfProducts(ata00, ata11, ata01, ata01)); invDet = IsFinite(invDet) ? invDet : 0.f; - dudx = DifferenceOfProducts(a11, b0x, a01, b1x) * invDet; - dvdx = DifferenceOfProducts(a00, b1x, a01, b0x) * invDet; + // Compute $\transpose{\XFORM{A}} \VEC{b}$ for $x$ and $y$ + Float atb0x = Dot(dpdu, dpdx), atb1x = Dot(dpdv, dpdx); + Float atb0y = Dot(dpdu, dpdy), atb1y = Dot(dpdv, dpdy); - dudy = DifferenceOfProducts(a11, b0y, a01, b1y) * invDet; - dvdy = DifferenceOfProducts(a00, b1y, a01, b0y) * invDet; + // Compute $u$ and $v$ partial derivatives with respect to $x$ and $y$ + dudx = DifferenceOfProducts(ata11, atb0x, ata01, atb1x) * invDet; + dvdx = DifferenceOfProducts(ata00, atb1x, ata01, atb0x) * invDet; + dudy = DifferenceOfProducts(ata11, atb0y, ata01, atb1y) * invDet; + dvdy = DifferenceOfProducts(ata00, atb1y, ata01, atb0y) * invDet; + // Clamp partial derivatives of $u$ and $v$ to reasonable values dudx = IsFinite(dudx) ? Clamp(dudx, -1e8f, 1e8f) : 0.f; dvdx = IsFinite(dvdx) ? Clamp(dvdx, -1e8f, 1e8f) : 0.f; dudy = IsFinite(dudy) ? Clamp(dudy, -1e8f, 1e8f) : 0.f;