From 523775f9b73044962f7aee5d3ff472afc33c1bdc Mon Sep 17 00:00:00 2001 From: "Day, Mike (NBCUniversal)" Date: Tue, 5 May 2026 13:51:34 -0700 Subject: [PATCH] MOONRAY-6034 (#2264) * Work in progress * Fix for MOONRAY-6034 * Apply Copilot feedback * Make some vars const Signed-off-by: Jon Lanz --- lib/rendering/pbr/core/Distribution.cc | 22 +++++++++++++++------- lib/rendering/pbr/core/Distribution.h | 6 +++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/rendering/pbr/core/Distribution.cc b/lib/rendering/pbr/core/Distribution.cc index 32665c01..2d706120 100644 --- a/lib/rendering/pbr/core/Distribution.cc +++ b/lib/rendering/pbr/core/Distribution.cc @@ -551,27 +551,35 @@ Distribution2D::tabulateCdf(Mapping mapping) } case CIRCULAR: { - // Weights outside of the maximal inscribed circle are set to black so - // we don't (or rarely) sample them. - // note: We are slighly pushing out the extents so we don't get full - // black for the edge scanlines. + // Set to near-zero the sampling weights of any texels which don't overlap the inscribed circle, + // so that we generate almost no samples inside such texels. + // TODO: support setting them to exactly zero. + float sclU, ofsU, sclV, ofsV; getScaleOffset(-0.5f, float(sizeU) - 0.5f, -1.0f, 1.0f, &sclU, &ofsU); getScaleOffset(-0.5f, float(sizeV) - 0.5f, -1.0f, 1.0f, &sclV, &ofsV); + const float halfTexelU = 2.0f / float(sizeU); + const float halfTexelV = 2.0f / float(sizeV); + tbb::parallel_for(tbb::blocked_range(0, sizeV, sizeV / sRangeDivider), [&](const tbb::blocked_range range) { for (size_type y = range.begin(); y < range.end(); ++y) { - float t = float(y) * sclV + ofsV; - float t2 = t * t; + const float tCenter = float(y) * sclV + ofsV; + const float tCorner = scene_rdl2::math::abs(tCenter) - halfTexelV; + const float t = max(tCorner, 0.0f); + const float t2 = t * t; for (size_type x = 0; x < sizeU; ++x) { - float s = float(x) * sclU + ofsU; + const float sCenter = float(x) * sclU + ofsU; + const float sCorner = scene_rdl2::math::abs(sCenter) - halfTexelU; + const float s = max(sCorner, 0.0f); if (s*s + t2 > 1.0f) { setWeight(x, y, sEpsilon); } } } }); + break; } default: { diff --git a/lib/rendering/pbr/core/Distribution.h b/lib/rendering/pbr/core/Distribution.h index f8867434..d75d19d6 100644 --- a/lib/rendering/pbr/core/Distribution.h +++ b/lib/rendering/pbr/core/Distribution.h @@ -212,9 +212,9 @@ class Distribution2D enum Mapping { NONE, ///< Undefined / un-initialized PLANAR, ///< Weighted by the image luminance, no-op. - CIRCULAR, ///< Used for disk light texture sampling, pixels outside of - ///< a maximal inscribed circle are set to black so we don't - ///< sample them. + CIRCULAR, ///< Used for disk light texture sampling, texels outside of + ///< the inscribed circle have their sampling weights set to + ///< near-zero so we don't sample them. HEMISPHERICAL, ///< Assuming a latlong input, the upper half of image is ///< weighted by math::sin(2pi * v), see (see pbrt section 14.6.5). ///< The bottom half of image is set to zero so it's not