From 1eea91e36989b9f5d5f5fe5069b2b8259bedade6 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Sat, 9 Jan 2021 07:30:14 -0800 Subject: [PATCH] Update from book source. Minor changes. Added built-in eta and k spectra for CuZn (brass) Fixed some small bugs in --upgrade Improve SampledWavelengths::ToString() GPU: issue warning on unsupported options (--force-diffuse, etc.) --- src/pbrt/cpu/integrators.cpp | 56 ++------------------------------- src/pbrt/cpu/integrators.h | 50 ++++++++++++++++++++++++++--- src/pbrt/film.cpp | 18 +++++++---- src/pbrt/gpu/pathintegrator.cpp | 31 ++++++++++++------ src/pbrt/media.h | 3 +- src/pbrt/parsedscene.cpp | 2 +- src/pbrt/parser.cpp | 2 ++ src/pbrt/samplers.h | 6 ++-- src/pbrt/util/check.h | 2 +- src/pbrt/util/spectrum.cpp | 34 ++++++++++++++++++-- 10 files changed, 124 insertions(+), 80 deletions(-) diff --git a/src/pbrt/cpu/integrators.cpp b/src/pbrt/cpu/integrators.cpp index bd458d7..171a6a8 100644 --- a/src/pbrt/cpu/integrators.cpp +++ b/src/pbrt/cpu/integrators.cpp @@ -56,57 +56,6 @@ std::string RandomWalkIntegrator::ToString() const { return StringPrintf("[ RandomWalkIntegrator maxDepth: %d ]", maxDepth); } -SampledSpectrum RandomWalkIntegrator::Li(RayDifferential ray, SampledWavelengths &lambda, - SamplerHandle sampler, - ScratchBuffer &scratchBuffer, - VisibleSurface *visibleSurface) const { - SampledSpectrum L = LiRandomWalk(ray, lambda, sampler, scratchBuffer, 0); - return SafeDiv(L, lambda.PDF()); -} - -SampledSpectrum RandomWalkIntegrator::LiRandomWalk(RayDifferential ray, - SampledWavelengths &lambda, - SamplerHandle sampler, - ScratchBuffer &scratchBuffer, - int depth) const { - SampledSpectrum L(0.f); - // Intersect ray with scene and return if no intersection - pstd::optional si = Intersect(ray); - if (!si) { - // Return emitted light from infinite light sources - for (LightHandle light : infiniteLights) - L += light.Le(ray, lambda); - return L; - } - SurfaceInteraction &isect = si->intr; - - // Get emitted radiance at surface intersection - L = isect.Le(-ray.d, lambda); - - // Terminate random walk if maximum depth has been reached - if (depth == maxDepth) - return L; - - // Compute BSDF at random walk intersection point - BSDF bsdf = isect.GetBSDF(ray, lambda, camera, scratchBuffer, sampler); - if (!bsdf) - return L; - - // Randomly sample direction leaving surface for random walk - Point2f u = sampler.Get2D(); - Vector3f wi = SampleUniformSphere(u); - - // Evaluate BSDF at surface for sampled direction - Vector3f wo = -ray.d; - SampledSpectrum beta = bsdf.f(wo, wi) * AbsDot(wi, isect.shading.n) / (1 / (4 * Pi)); - if (!beta) - return L; - - // Recursively trace ray to estimate incident radiance at surface - ray = isect.SpawnRay(wi); - return L + beta * LiRandomWalk(ray, lambda, sampler, scratchBuffer, depth + 1); -} - // Integrator Method Definitions Integrator::~Integrator() {} @@ -241,7 +190,8 @@ void ImageTileIntegrator::Render() { waveEnd = std::min(spp, waveEnd + nextWaveSize); if (!referenceImage) nextWaveSize = std::min(2 * nextWaveSize, 64); - if (waveStart == spp) progress.Done(); + if (waveStart == spp) + progress.Done(); // Optionally write current image to disk if (waveStart == spp || Options->writePartialImages || referenceImage) { @@ -299,7 +249,7 @@ void RayIntegrator::EvaluatePixelSample(Point2i pPixel, int sampleIndex, DCHECK_LT(Length(cameraRay->ray.d), 1.001f); // Scale camera ray differentials based on sampling rate Float rayDiffScale = - std::max(.125, 1 / std::sqrt((Float)sampler.SamplesPerPixel())); + std::max(.125f, 1 / std::sqrt((Float)sampler.SamplesPerPixel())); if (!Options->disablePixelJitter) cameraRay->ray.ScaleDifferentials(rayDiffScale); diff --git a/src/pbrt/cpu/integrators.h b/src/pbrt/cpu/integrators.h index c2c9d16..128f4ed 100644 --- a/src/pbrt/cpu/integrators.h +++ b/src/pbrt/cpu/integrators.h @@ -121,9 +121,6 @@ class RandomWalkIntegrator : public RayIntegrator { RandomWalkIntegrator(int maxDepth, CameraHandle camera, SamplerHandle sampler, PrimitiveHandle aggregate, std::vector lights) : RayIntegrator(camera, sampler, aggregate, lights), maxDepth(maxDepth) {} - SampledSpectrum Li(RayDifferential ray, SampledWavelengths &lambda, - SamplerHandle sampler, ScratchBuffer &scratchBuffer, - VisibleSurface *visibleSurface = nullptr) const; static std::unique_ptr Create( const ParameterDictionary ¶meters, CameraHandle camera, SamplerHandle sampler, @@ -131,11 +128,56 @@ class RandomWalkIntegrator : public RayIntegrator { std::string ToString() const; + SampledSpectrum Li(RayDifferential ray, SampledWavelengths &lambda, + SamplerHandle sampler, ScratchBuffer &scratchBuffer, + VisibleSurface *visibleSurface) const { + SampledSpectrum L = LiRandomWalk(ray, lambda, sampler, scratchBuffer, 0); + return SafeDiv(L, lambda.PDF()); + } + private: // RandomWalkIntegrator Private Methods SampledSpectrum LiRandomWalk(RayDifferential ray, SampledWavelengths &lambda, SamplerHandle sampler, ScratchBuffer &scratchBuffer, - int depth) const; + int depth) const { + SampledSpectrum L(0.f); + // Intersect ray with scene and return if no intersection + pstd::optional si = Intersect(ray); + if (!si) { + // Return emitted light from infinite light sources + for (LightHandle light : infiniteLights) + L += light.Le(ray, lambda); + return L; + } + SurfaceInteraction &isect = si->intr; + + // Get emitted radiance at surface intersection + L = isect.Le(-ray.d, lambda); + + // Terminate random walk if maximum depth has been reached + if (depth == maxDepth) + return L; + + // Compute BSDF at random walk intersection point + BSDF bsdf = isect.GetBSDF(ray, lambda, camera, scratchBuffer, sampler); + if (!bsdf) + return L; + + // Randomly sample direction leaving surface for random walk + Point2f u = sampler.Get2D(); + Vector3f wi = SampleUniformSphere(u); + + // Evaluate BSDF at surface for sampled direction + Vector3f wo = -ray.d; + SampledSpectrum beta = + bsdf.f(wo, wi) * AbsDot(wi, isect.shading.n) / (1 / (4 * Pi)); + if (!beta) + return L; + + // Recursively trace ray to estimate incident radiance at surface + ray = isect.SpawnRay(wi); + return L + beta * LiRandomWalk(ray, lambda, sampler, scratchBuffer, depth + 1); + } // RandomWalkIntegrator Private Members int maxDepth; diff --git a/src/pbrt/film.cpp b/src/pbrt/film.cpp index 465ff1c..0a2a956 100644 --- a/src/pbrt/film.cpp +++ b/src/pbrt/film.cpp @@ -555,9 +555,12 @@ Image RGBFilm::GetImage(ImageMetadata *metadata, Float splatScale) { RGB rgb = GetPixelRGB(p, splatScale); if (writeFP16 && std::max({rgb.r, rgb.g, rgb.b}) > 65504) { - if (rgb.r > 65504) rgb.r = 65504; - if (rgb.g > 65504) rgb.g = 65504; - if (rgb.b > 65504) rgb.b = 65504; + if (rgb.r > 65504) + rgb.r = 65504; + if (rgb.g > 65504) + rgb.g = 65504; + if (rgb.b > 65504) + rgb.b = 65504; ++nClamped; } @@ -748,9 +751,12 @@ Image GBufferFilm::GetImage(ImageMetadata *metadata, Float splatScale) { rgb = outputRGBFromSensorRGB * rgb; if (writeFP16 && std::max({rgb.r, rgb.g, rgb.b}) > 65504) { - if (rgb.r > 65504) rgb.r = 65504; - if (rgb.g > 65504) rgb.g = 65504; - if (rgb.b > 65504) rgb.b = 65504; + if (rgb.r > 65504) + rgb.r = 65504; + if (rgb.g > 65504) + rgb.g = 65504; + if (rgb.b > 65504) + rgb.b = 65504; ++nClamped; } diff --git a/src/pbrt/gpu/pathintegrator.cpp b/src/pbrt/gpu/pathintegrator.cpp index f69d99a..70b088c 100644 --- a/src/pbrt/gpu/pathintegrator.cpp +++ b/src/pbrt/gpu/pathintegrator.cpp @@ -110,9 +110,8 @@ GPUPathIntegrator::GPUPathIntegrator(Allocator alloc, const ParsedScene &scene) scene.camera.cameraTransform, outsideMedium, &light.loc, alloc); if (l.Is() || l.Is() || - l.Is()) { + l.Is()) envLights.push_back(l); - } allLights.push_back(l); } @@ -181,6 +180,18 @@ GPUPathIntegrator::GPUPathIntegrator(Allocator alloc, const ParsedScene &scene) regularize = scene.integrator.parameters.GetOneBool("regularize", false); maxDepth = scene.integrator.parameters.GetOneInt("maxdepth", 5); + // Warn about unsupported stuff... + if (Options->forceDiffuse) + Warning("The GPU rendering path does not support --force-diffuse."); + if (Options->writePartialImages) + Warning("The GPU rendering path does not support --write-partial-images."); + if (Options->recordPixelStatistics) + Warning("The GPU rendering path does not support --pixelstats."); + if (!Options->mseReferenceImage.empty()) + Warning("The GPU rendering path does not support --mse-reference-image."); + if (!Options->mseReferenceOutput.empty()) + Warning("The GPU rendering path does not support --mse-reference-out."); + /////////////////////////////////////////////////////////////////////////// // Allocate storage for all of the queues/buffers... @@ -451,13 +462,13 @@ void GPUPathIntegrator::HandleEscapedRays(int depth) { for (const auto &light : envLights) { if (SampledSpectrum Le = light.Le(Ray(w.rayo, w.rayd), w.lambda); Le) { // Compute path radiance contribution from infinite light - - PBRT_DBG("L %f %f %f %f T_hat %f %f %f %f Le %f %f %f %f", L[0], L[1], L[2], - L[3], w.T_hat[0], w.T_hat[1], w.T_hat[2], w.T_hat[3], Le[0], Le[1], - Le[2], Le[3]); + PBRT_DBG("L %f %f %f %f T_hat %f %f %f %f Le %f %f %f %f", L[0], L[1], + L[2], L[3], w.T_hat[0], w.T_hat[1], w.T_hat[2], w.T_hat[3], + Le[0], Le[1], Le[2], Le[3]); PBRT_DBG("pdf uni %f %f %f %f pdf nee %f %f %f %f", w.uniPathPDF[0], - w.uniPathPDF[1], w.uniPathPDF[2], w.uniPathPDF[3], w.lightPathPDF[0], - w.lightPathPDF[1], w.lightPathPDF[2], w.lightPathPDF[3]); + w.uniPathPDF[1], w.uniPathPDF[2], w.uniPathPDF[3], + w.lightPathPDF[0], w.lightPathPDF[1], w.lightPathPDF[2], + w.lightPathPDF[3]); if (depth == 0 || w.specularBounce) { L += w.T_hat * Le / w.uniPathPDF.Average(); @@ -475,8 +486,8 @@ void GPUPathIntegrator::HandleEscapedRays(int depth) { if (L) { L = SafeDiv(L, w.lambda.PDF()); - PBRT_DBG("Added L %f %f %f %f for escaped ray pixel index %d\n", L[0], L[1], - L[2], L[3], w.pixelIndex); + PBRT_DBG("Added L %f %f %f %f for escaped ray pixel index %d\n", L[0], + L[1], L[2], L[3], w.pixelIndex); L += pixelSampleState.L[w.pixelIndex]; pixelSampleState.L[w.pixelIndex] = L; diff --git a/src/pbrt/media.h b/src/pbrt/media.h index 2d3308e..cc23e07 100644 --- a/src/pbrt/media.h +++ b/src/pbrt/media.h @@ -103,7 +103,8 @@ class HomogeneousMedium { F callback) const { // Normalize ray direction for homogeneous medium sampling tMax *= Length(ray.d); - if (std::isinf(tMax)) tMax = std::numeric_limits::max(); + if (std::isinf(tMax)) + tMax = std::numeric_limits::max(); ray.d = Normalize(ray.d); // Compute _SampledSpectrum_ scattering properties for medium diff --git a/src/pbrt/parsedscene.cpp b/src/pbrt/parsedscene.cpp index f63f5cc..9d0132b 100644 --- a/src/pbrt/parsedscene.cpp +++ b/src/pbrt/parsedscene.cpp @@ -1485,7 +1485,7 @@ void FormattingScene::LightSource(const std::string &name, ParsedParameterVector "Please modify your scene file manually."); return; } - dict.RemoveInt("nsamples"); + dict.RemoveInt("samples"); if (dict.GetOneString("mapname", "").empty() == false) { if (name == "infinite" && !upgradeRGBToScale(&dict, "L", &totalScale)) { diff --git a/src/pbrt/parser.cpp b/src/pbrt/parser.cpp index 2628266..3030995 100644 --- a/src/pbrt/parser.cpp +++ b/src/pbrt/parser.cpp @@ -421,6 +421,8 @@ static ParsedParameterVector parseParameters( if (formatting) { // close enough: upgrade... if (param->type == "point") param->type = "point3"; + if (param->type == "vector") + param->type = "vector3"; if (param->type == "color") param->type = "rgb"; } diff --git a/src/pbrt/samplers.h b/src/pbrt/samplers.h index 894ef55..79ae2ac 100644 --- a/src/pbrt/samplers.h +++ b/src/pbrt/samplers.h @@ -280,8 +280,10 @@ class ZSobolSampler { void StartPixelSample(const Point2i &p, int index, int dim) { dimension = dim; bool pow2Samples = log2SamplesPerPixel & 1; - if (pow2Samples) index <<= 1; - mortonIndex = (EncodeMorton2(p.x, p.y) << ((log2SamplesPerPixel + 1) & ~1)) | index; + if (pow2Samples) + index <<= 1; + mortonIndex = + (EncodeMorton2(p.x, p.y) << ((log2SamplesPerPixel + 1) & ~1)) | index; } PBRT_CPU_GPU diff --git a/src/pbrt/util/check.h b/src/pbrt/util/check.h index b389a7b..653f534 100644 --- a/src/pbrt/util/check.h +++ b/src/pbrt/util/check.h @@ -81,7 +81,7 @@ void PrintStackTrace(); #define DCHECK_LT(a, b) EMPTY_CHECK #define DCHECK_LE(a, b) EMPTY_CHECK -#endif // !defined(NDEBUG) +#endif #define CHECK_RARE_TO_STRING(x) #x #define CHECK_RARE_EXPAND_AND_TO_STRING(x) CHECK_RARE_TO_STRING(x) diff --git a/src/pbrt/util/spectrum.cpp b/src/pbrt/util/spectrum.cpp index 3908af5..2ff1037 100644 --- a/src/pbrt/util/spectrum.cpp +++ b/src/pbrt/util/spectrum.cpp @@ -174,10 +174,13 @@ std::string DenselySampledSpectrum::ToString() const { } std::string SampledWavelengths::ToString() const { - std::string r = "["; + std::string r = "[ SampledWavelengths lambda: ["; for (size_t i = 0; i < lambda.size(); ++i) r += StringPrintf(" %f%c", lambda[i], i != lambda.size() - 1 ? ',' : ' '); - r += ']'; + r += "] pdf: ["; + for (size_t i = 0; i < lambda.size(); ++i) + r += StringPrintf(" %f%c", pdf[i], i != pdf.size() - 1 ? ',' : ' '); + r += "] ]"; return r; } @@ -1266,6 +1269,28 @@ const Float Cu_k[] = { 5.034125, 826.561157, 5.260000, 855.063293, 5.485625, 885.601257, 5.717000, }; +const Float CuZn_eta[] = { + 290, 1.358, 300, 1.388, 310, 1.419, 320, 1.446, 330, 1.473, 340, 1.494, 350, 1.504, + 360, 1.503, 370, 1.497, 380, 1.487, 390, 1.471, 400, 1.445, 410, 1.405, 420, 1.350, + 430, 1.278, 440, 1.191, 450, 1.094, 460, 0.994, 470, 0.900, 480, 0.816, 490, 0.745, + 500, 0.686, 510, 0.639, 520, 0.602, 530, 0.573, 540, 0.549, 550, 0.527, 560, 0.505, + 570, 0.484, 580, 0.468, 590, 0.460, 600, 0.450, 610, 0.452, 620, 0.449, 630, 0.445, + 640, 0.444, 650, 0.444, 660, 0.445, 670, 0.444, 680, 0.444, 690, 0.445, 700, 0.446, + 710, 0.448, 720, 0.450, 730, 0.452, 740, 0.455, 750, 0.457, 760, 0.458, 770, 0.460, + 780, 0.464, 790, 0.469, 800, 0.473, 810, 0.478, 820, 0.481, 830, 0.483, 840, 0.486, + 850, 0.490, 860, 0.494, 870, 0.500, 880, 0.507, 890, 0.515}; + +const Float CuZn_k[] = { + 290, 1.688, 300, 1.731, 310, 1.764, 320, 1.789, 330, 1.807, 340, 1.815, 350, 1.815, + 360, 1.815, 370, 1.818, 380, 1.818, 390, 1.813, 400, 1.805, 410, 1.794, 420, 1.786, + 430, 1.784, 440, 1.797, 450, 1.829, 460, 1.883, 470, 1.957, 480, 2.046, 490, 2.145, + 500, 2.250, 510, 2.358, 520, 2.464, 530, 2.568, 540, 2.668, 550, 2.765, 560, 2.860, + 570, 2.958, 580, 3.059, 590, 3.159, 600, 3.253, 610, 3.345, 620, 3.434, 630, 3.522, + 640, 3.609, 650, 3.695, 660, 3.778, 670, 3.860, 680, 3.943, 690, 4.025, 700, 4.106, + 710, 4.186, 720, 4.266, 730, 4.346, 740, 4.424, 750, 4.501, 760, 4.579, 770, 4.657, + 780, 4.737, 790, 4.814, 800, 4.890, 810, 4.965, 820, 5.039, 830, 5.115, 840, 5.192, + 850, 5.269, 860, 5.346, 870, 5.423, 880, 5.500, 890, 5.575}; + const Float MgO_eta[] = { 309.950012, 1.798000, 330.613007, 1.785000, 351.118988, 1.776800, 355.549011, 1.775500, 360.932007, 1.773200, 361.141998, 1.773180, 364.968994, 1.771860, @@ -2661,6 +2686,9 @@ void Init(Allocator alloc) { SpectrumHandle auk = PiecewiseLinearSpectrum::FromInterleaved(Au_k, false, alloc); SpectrumHandle cueta = PiecewiseLinearSpectrum::FromInterleaved(Cu_eta, false, alloc); SpectrumHandle cuk = PiecewiseLinearSpectrum::FromInterleaved(Cu_k, false, alloc); + SpectrumHandle cuzneta = + PiecewiseLinearSpectrum::FromInterleaved(CuZn_eta, false, alloc); + SpectrumHandle cuznk = PiecewiseLinearSpectrum::FromInterleaved(CuZn_k, false, alloc); SpectrumHandle mgoeta = PiecewiseLinearSpectrum::FromInterleaved(MgO_eta, false, alloc); SpectrumHandle mgok = PiecewiseLinearSpectrum::FromInterleaved(MgO_k, false, alloc); @@ -2699,6 +2727,8 @@ void Init(Allocator alloc) { {"metal-Au-k", auk}, {"metal-Cu-eta", cueta}, {"metal-Cu-k", cuk}, + {"metal-CuZn-eta", cuzneta}, + {"metal-CuZn-k", cuznk}, {"metal-MgO-eta", mgoeta}, {"metal-MgO-k", mgok}, {"metal-TiO2-eta", tio2eta}, -- GitLab