提交 1eea91e3 编写于 作者: M Matt Pharr

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.)
上级 61933b85
......@@ -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<ShapeIntersection> 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<Float>(.125, 1 / std::sqrt((Float)sampler.SamplesPerPixel()));
std::max<Float>(.125f, 1 / std::sqrt((Float)sampler.SamplesPerPixel()));
if (!Options->disablePixelJitter)
cameraRay->ray.ScaleDifferentials(rayDiffScale);
......
......@@ -121,9 +121,6 @@ class RandomWalkIntegrator : public RayIntegrator {
RandomWalkIntegrator(int maxDepth, CameraHandle camera, SamplerHandle sampler,
PrimitiveHandle aggregate, std::vector<LightHandle> 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<RandomWalkIntegrator> Create(
const ParameterDictionary &parameters, 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<ShapeIntersection> 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;
......
......@@ -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;
}
......
......@@ -110,9 +110,8 @@ GPUPathIntegrator::GPUPathIntegrator(Allocator alloc, const ParsedScene &scene)
scene.camera.cameraTransform, outsideMedium, &light.loc, alloc);
if (l.Is<UniformInfiniteLight>() || l.Is<ImageInfiniteLight>() ||
l.Is<PortalImageInfiniteLight>()) {
l.Is<PortalImageInfiniteLight>())
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;
......
......@@ -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<Float>::max();
if (std::isinf(tMax))
tMax = std::numeric_limits<Float>::max();
ray.d = Normalize(ray.d);
// Compute _SampledSpectrum_ scattering properties for medium
......
......@@ -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)) {
......
......@@ -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";
}
......
......@@ -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
......
......@@ -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)
......
......@@ -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},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册