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

Add (and use) LightBase::LookupSpectrum() with InternCache

The lights now all use an InternCache for their DenselySampledSpectrum
values, saving a significant amount of memory for scenes with many
area lights that have the same emission spectra. (Partial fix to issue #183.)
上级 13acd59c
......@@ -91,8 +91,7 @@ std::vector<TestScene> GetScenes() {
ConstantSpectrum I(1);
Float scale = Pi / SpectrumToPhotometric(&I);
std::vector<Light> lights;
lights.push_back(
new PointLight(identity, MediumInterface(), &I, scale, Allocator()));
lights.push_back(new PointLight(identity, MediumInterface(), &I, scale));
scenes.push_back({bvh, lights, "Sphere, 1 light, Kd = 0.5", 1.0});
}
......@@ -118,14 +117,10 @@ std::vector<TestScene> GetScenes() {
ConstantSpectrum I(1);
Float scale = Pi / (4 * SpectrumToPhotometric(&I));
std::vector<Light> lights;
lights.push_back(
new PointLight(identity, MediumInterface(), &I, scale, Allocator()));
lights.push_back(
new PointLight(identity, MediumInterface(), &I, scale, Allocator()));
lights.push_back(
new PointLight(identity, MediumInterface(), &I, scale, Allocator()));
lights.push_back(
new PointLight(identity, MediumInterface(), &I, scale, Allocator()));
lights.push_back(new PointLight(identity, MediumInterface(), &I, scale));
lights.push_back(new PointLight(identity, MediumInterface(), &I, scale));
lights.push_back(new PointLight(identity, MediumInterface(), &I, scale));
lights.push_back(new PointLight(identity, MediumInterface(), &I, scale));
scenes.push_back({bvh, lights, "Sphere, 1 light, Kd = 0.5", 1.0});
}
......@@ -146,7 +141,7 @@ std::vector<TestScene> GetScenes() {
Float scale = 0.5 / SpectrumToPhotometric(&Le);
Light areaLight =
new DiffuseAreaLight(identity, MediumInterface(), &Le, scale, sphere, nullptr,
Image(), nullptr, false, Allocator());
Image(), nullptr, false);
std::vector<Light> lights;
lights.push_back(areaLight);
......
......@@ -9,11 +9,15 @@
#include <pbrt/lights.h>
#include <pbrt/cameras.h>
#ifdef PBRT_BUILD_GPU_RENDERER
#include <pbrt/gpu/memory.h>
#endif // PBRT_BUILD_GPU_RENDERER
#include <pbrt/paramdict.h>
#include <pbrt/samplers.h>
#include <pbrt/shapes.h>
#include <pbrt/util/color.h>
#include <pbrt/util/colorspace.h>
#include <pbrt/util/containers.h>
#include <pbrt/util/error.h>
#include <pbrt/util/file.h>
#include <pbrt/util/float.h>
......@@ -26,12 +30,32 @@
#include <pbrt/util/stats.h>
#include <algorithm>
#include <mutex>
namespace pbrt {
STAT_COUNTER("Scene/Lights", numLights);
STAT_COUNTER("Scene/AreaLights", numAreaLights);
InternCache<DenselySampledSpectrum, DenselySampledSpectrum::Hash> *LightBase::spectrumCache;
const DenselySampledSpectrum *LightBase::LookupSpectrum(Spectrum s) {
static std::mutex mutex;
mutex.lock();
if (!spectrumCache)
spectrumCache = new InternCache<DenselySampledSpectrum, DenselySampledSpectrum::Hash>(
#ifdef PBRT_BUILD_GPU_RENDERER
Options->useGPU ? Allocator(&CUDATrackedMemoryResource::singleton) :
#endif
Allocator{});
mutex.unlock();
return spectrumCache->Lookup(DenselySampledSpectrum(s),
[](Allocator alloc, const DenselySampledSpectrum &s) {
return alloc.new_object<DenselySampledSpectrum>(s, alloc);
});
}
// Light Method Definitions
std::string LightLiSample::ToString() const {
return StringPrintf("[ LightLiSample L: %s wi: %s pdf: %f pLight: %s ]", L, wi, pdf,
......@@ -153,12 +177,12 @@ Float LightBounds::Importance(Point3f p, Normal3f n) const {
// PointLight Method Definitions
SampledSpectrum PointLight::Phi(SampledWavelengths lambda) const {
return 4 * Pi * scale * I.Sample(lambda);
return 4 * Pi * scale * I->Sample(lambda);
}
pstd::optional<LightBounds> PointLight::Bounds() const {
Point3f p = renderFromLight(Point3f(0, 0, 0));
Float phi = 4 * Pi * scale * I.MaxValue();
Float phi = 4 * Pi * scale * I->MaxValue();
return LightBounds(Bounds3f(p, p), Vector3f(0, 0, 1), phi, std::cos(Pi),
std::cos(Pi / 2), false);
}
......@@ -168,7 +192,7 @@ pstd::optional<LightLeSample> PointLight::SampleLe(Point2f u1, Point2f u2,
Float time) const {
Point3f p = renderFromLight(Point3f(0, 0, 0));
Ray ray(p, SampleUniformSphere(u1), time, mediumInterface.outside);
return LightLeSample(scale * I.Sample(lambda), ray, 1, UniformSpherePDF());
return LightLeSample(scale * I->Sample(lambda), ray, 1, UniformSpherePDF());
}
void PointLight::PDF_Le(const Ray &, Float *pdfPos, Float *pdfDir) const {
......@@ -200,12 +224,12 @@ PointLight *PointLight::Create(const Transform &renderFromLight, Medium medium,
Transform tf = Translate(Vector3f(from.x, from.y, from.z));
Transform finalRenderFromLight(renderFromLight * tf);
return alloc.new_object<PointLight>(finalRenderFromLight, medium, I, sc, alloc);
return alloc.new_object<PointLight>(finalRenderFromLight, medium, I, sc);
}
// DistantLight Method Definitions
SampledSpectrum DistantLight::Phi(SampledWavelengths lambda) const {
return scale * Lemit.Sample(lambda) * Pi * Sqr(sceneRadius);
return scale * Lemit->Sample(lambda) * Pi * Sqr(sceneRadius);
}
pstd::optional<LightLeSample> DistantLight::SampleLe(Point2f u1, Point2f u2,
......@@ -220,7 +244,7 @@ pstd::optional<LightLeSample> DistantLight::SampleLe(Point2f u1, Point2f u2,
// Compute _DistantLight_ light ray
Ray ray(pDisk + sceneRadius * w, -w, time);
return LightLeSample(scale * Lemit.Sample(lambda), ray, 1 / (Pi * Sqr(sceneRadius)),
return LightLeSample(scale * Lemit->Sample(lambda), ray, 1 / (Pi * Sqr(sceneRadius)),
1);
}
......@@ -265,7 +289,7 @@ DistantLight *DistantLight::Create(const Transform &renderFromLight,
sc *= E_v / k_e;
}
return alloc.new_object<DistantLight>(finalRenderFromLight, L, sc, alloc);
return alloc.new_object<DistantLight>(finalRenderFromLight, L, sc);
}
STAT_MEMORY_COUNTER("Memory/Light image and distributions", imageBytes);
......@@ -512,10 +536,10 @@ ProjectionLight *ProjectionLight::Create(const Transform &renderFromLight, Mediu
// GoniometricLight Method Definitions
GoniometricLight::GoniometricLight(const Transform &renderFromLight,
const MediumInterface &mediumInterface, Spectrum Iemit,
Float scale, Image im, Allocator alloc)
const MediumInterface &mediumInterface,
Spectrum Iemit, Float scale, Image im, Allocator alloc)
: LightBase(LightType::DeltaPosition, renderFromLight, mediumInterface),
Iemit(Iemit, alloc),
Iemit(LookupSpectrum(Iemit)),
scale(scale),
image(std::move(im)),
distrib(alloc) {
......@@ -549,7 +573,7 @@ SampledSpectrum GoniometricLight::Phi(SampledWavelengths lambda) const {
for (int y = 0; y < image.Resolution().y; ++y)
for (int x = 0; x < image.Resolution().x; ++x)
sumY += image.GetChannel({x, y}, 0);
return scale * Iemit.Sample(lambda) * 4 * Pi * sumY /
return scale * Iemit->Sample(lambda) * 4 * Pi * sumY /
(image.Resolution().x * image.Resolution().y);
}
......@@ -558,7 +582,7 @@ pstd::optional<LightBounds> GoniometricLight::Bounds() const {
for (int y = 0; y < image.Resolution().y; ++y)
for (int x = 0; x < image.Resolution().x; ++x)
sumY += image.GetChannel({x, y}, 0);
Float phi = scale * Iemit.MaxValue() * 4 * Pi * sumY /
Float phi = scale * Iemit->MaxValue() * 4 * Pi * sumY /
(image.Resolution().x * image.Resolution().y);
Point3f p = renderFromLight(Point3f(0, 0, 0));
......@@ -675,10 +699,10 @@ GoniometricLight *GoniometricLight::Create(const Transform &renderFromLight,
// DiffuseAreaLight Method Definitions
DiffuseAreaLight::DiffuseAreaLight(const Transform &renderFromLight,
const MediumInterface &mediumInterface, Spectrum Le,
Float scale, const Shape shape, FloatTexture alpha,
const MediumInterface &mediumInterface,
Spectrum Le, Float scale, const Shape shape, FloatTexture alpha,
Image im, const RGBColorSpace *imageColorSpace,
bool twoSided, Allocator alloc)
bool twoSided)
: LightBase(
[](FloatTexture alpha) {
// Special case handling for area lights with constant zero-valued alpha
......@@ -702,7 +726,7 @@ DiffuseAreaLight::DiffuseAreaLight(const Transform &renderFromLight,
alpha(type == LightType::Area ? alpha : nullptr),
area(shape.Area()),
twoSided(twoSided),
Lemit(Le, alloc),
Lemit(LookupSpectrum(Le)),
scale(scale),
image(std::move(im)),
imageColorSpace(imageColorSpace) {
......@@ -774,7 +798,7 @@ SampledSpectrum DiffuseAreaLight::Phi(SampledWavelengths lambda) const {
L *= scale / (image.Resolution().x * image.Resolution().y);
} else
L = Lemit.Sample(lambda) * scale;
L = Lemit->Sample(lambda) * scale;
return Pi * (twoSided ? 2 : 1) * area * L;
}
......@@ -791,7 +815,7 @@ pstd::optional<LightBounds> DiffuseAreaLight::Bounds() const {
phi /= 3 * image.Resolution().x * image.Resolution().y;
} else
phi = Lemit.MaxValue();
phi = Lemit->MaxValue();
phi *= scale * area * Pi;
DirectionCone nb = shape.NormalBounds();
......@@ -934,19 +958,19 @@ DiffuseAreaLight *DiffuseAreaLight::Create(const Transform &renderFromLight,
return alloc.new_object<DiffuseAreaLight>(renderFromLight, medium, L, scale, shape,
alphaTex, std::move(image), imageColorSpace,
twoSided, alloc);
twoSided);
}
// UniformInfiniteLight Method Definitions
UniformInfiniteLight::UniformInfiniteLight(const Transform &renderFromLight,
Spectrum Lemit, Float scale, Allocator alloc)
Spectrum Lemit, Float scale)
: LightBase(LightType::Infinite, renderFromLight, MediumInterface()),
Lemit(Lemit, alloc),
Lemit(LookupSpectrum(Lemit)),
scale(scale) {}
SampledSpectrum UniformInfiniteLight::Le(const Ray &ray,
const SampledWavelengths &lambda) const {
return scale * Lemit.Sample(lambda);
return scale * Lemit->Sample(lambda);
}
pstd::optional<LightLiSample> UniformInfiniteLight::SampleLi(
......@@ -957,7 +981,7 @@ pstd::optional<LightLiSample> UniformInfiniteLight::SampleLi(
// Return uniform spherical sample for uniform infinite light
Vector3f wi = SampleUniformSphere(u);
Float pdf = UniformSpherePDF();
return LightLiSample(scale * Lemit.Sample(lambda), wi, pdf,
return LightLiSample(scale * Lemit->Sample(lambda), wi, pdf,
Interaction(ctx.p() + wi * (2 * sceneRadius), &mediumInterface));
}
......@@ -969,7 +993,7 @@ Float UniformInfiniteLight::PDF_Li(LightSampleContext ctx, Vector3f w,
}
SampledSpectrum UniformInfiniteLight::Phi(SampledWavelengths lambda) const {
return 4 * Pi * Pi * Sqr(sceneRadius) * scale * Lemit.Sample(lambda);
return 4 * Pi * Pi * Sqr(sceneRadius) * scale * Lemit->Sample(lambda);
}
pstd::optional<LightLeSample> UniformInfiniteLight::SampleLe(Point2f u1, Point2f u2,
......@@ -988,7 +1012,7 @@ pstd::optional<LightLeSample> UniformInfiniteLight::SampleLe(Point2f u1, Point2f
Float pdfPos = 1 / (Pi * Sqr(sceneRadius));
Float pdfDir = UniformSpherePDF();
return LightLeSample(scale * Lemit.Sample(lambda), ray, pdfPos, pdfDir);
return LightLeSample(scale * Lemit->Sample(lambda), ray, pdfPos, pdfDir);
}
void UniformInfiniteLight::PDF_Le(const Ray &ray, Float *pdfPos, Float *pdfDir) const {
......@@ -1341,9 +1365,9 @@ std::string PortalImageInfiniteLight::ToString() const {
// SpotLight Method Definitions
SpotLight::SpotLight(const Transform &renderFromLight,
const MediumInterface &mediumInterface, Spectrum Iemit, Float scale,
Float totalWidth, Float falloffStart, Allocator alloc)
Float totalWidth, Float falloffStart)
: LightBase(LightType::DeltaPosition, renderFromLight, mediumInterface),
Iemit(Iemit, alloc),
Iemit(LookupSpectrum(Iemit)),
scale(scale),
cosFalloffEnd(std::cos(Radians(totalWidth))),
cosFalloffStart(std::cos(Radians(falloffStart))) {
......@@ -1356,18 +1380,18 @@ Float SpotLight::PDF_Li(LightSampleContext, Vector3f, bool allowIncompletePDF) c
SampledSpectrum SpotLight::I(Vector3f w, SampledWavelengths lambda) const {
return SmoothStep(CosTheta(w), cosFalloffEnd, cosFalloffStart) * scale *
Iemit.Sample(lambda);
Iemit->Sample(lambda);
}
SampledSpectrum SpotLight::Phi(SampledWavelengths lambda) const {
return scale * Iemit.Sample(lambda) * 2 * Pi *
return scale * Iemit->Sample(lambda) * 2 * Pi *
((1 - cosFalloffStart) + (cosFalloffStart - cosFalloffEnd) / 2);
}
pstd::optional<LightBounds> SpotLight::Bounds() const {
Point3f p = renderFromLight(Point3f(0, 0, 0));
Vector3f w = Normalize(renderFromLight(Vector3f(0, 0, 1)));
Float phi = scale * Iemit.MaxValue() * 4 * Pi;
Float phi = scale * Iemit->MaxValue() * 4 * Pi;
Float cosTheta_e = std::cos(std::acos(cosFalloffEnd) - std::acos(cosFalloffStart));
// Allow a little slop here to deal with fp round-off error in the computation of
// cosTheta_p in the importance function.
......@@ -1457,7 +1481,7 @@ SpotLight *SpotLight::Create(const Transform &renderFromLight, Medium medium,
}
return alloc.new_object<SpotLight>(finalRenderFromLight, medium, I, sc, coneangle,
coneangle - conedelta, alloc);
coneangle - conedelta);
}
SampledSpectrum Light::Phi(SampledWavelengths lambda) const {
......@@ -1543,7 +1567,7 @@ Light Light::Create(const std::string &name, const ParameterDictionary &paramete
// Default: color space's std illuminant
light = alloc.new_object<UniformInfiniteLight>(
renderFromLight, &colorSpace->illuminant, scale, alloc);
renderFromLight, &colorSpace->illuminant, scale);
} else if (!L.empty() && portal.empty()) {
if (!filename.empty())
ErrorExit(loc, "Can't specify both emission \"L\" and "
......@@ -1560,8 +1584,7 @@ Light Light::Create(const std::string &name, const ParameterDictionary &paramete
scale *= E_v / k_e;
}
light = alloc.new_object<UniformInfiniteLight>(renderFromLight, L[0], scale,
alloc);
light = alloc.new_object<UniformInfiniteLight>(renderFromLight, L[0], scale);
} else {
// Either an image was provided or it's "L" with a portal.
ImageAndMetadata imageAndMetadata;
......
......@@ -157,21 +157,26 @@ class LightBase {
}
protected:
static const DenselySampledSpectrum *LookupSpectrum(Spectrum s);
std::string BaseToString() const;
// LightBase Protected Members
LightType type;
Transform renderFromLight;
MediumInterface mediumInterface;
private:
static InternCache<DenselySampledSpectrum, DenselySampledSpectrum::Hash> *spectrumCache;
};
// PointLight Definition
class PointLight : public LightBase {
public:
// PointLight Public Methods
PointLight(Transform renderFromLight, MediumInterface mediumInterface, Spectrum I,
Float scale, Allocator alloc)
PointLight(Transform renderFromLight, MediumInterface mediumInterface,
Spectrum I, Float scale)
: LightBase(LightType::DeltaPosition, renderFromLight, mediumInterface),
I(I, alloc),
I(LookupSpectrum(I)),
scale(scale) {}
static PointLight *Create(const Transform &renderFromLight, Medium medium,
......@@ -202,7 +207,7 @@ class PointLight : public LightBase {
bool allowIncompletePDF) const {
Point3f p = renderFromLight(Point3f(0, 0, 0));
Vector3f wi = Normalize(p - ctx.p());
SampledSpectrum Li = scale * I.Sample(lambda) / DistanceSquared(p, ctx.p());
SampledSpectrum Li = scale * I->Sample(lambda) / DistanceSquared(p, ctx.p());
return LightLiSample(Li, wi, 1, Interaction(p, &mediumInterface));
}
......@@ -213,7 +218,7 @@ class PointLight : public LightBase {
private:
// PointLight Private Members
DenselySampledSpectrum I;
const DenselySampledSpectrum *I;
Float scale;
};
......@@ -221,10 +226,9 @@ class PointLight : public LightBase {
class DistantLight : public LightBase {
public:
// DistantLight Public Methods
DistantLight(const Transform &renderFromLight, Spectrum Lemit, Float scale,
Allocator alloc)
DistantLight(const Transform &renderFromLight, Spectrum Lemit, Float scale)
: LightBase(LightType::DeltaDirection, renderFromLight, {}),
Lemit(Lemit, alloc),
Lemit(LookupSpectrum(Lemit)),
scale(scale) {}
static DistantLight *Create(const Transform &renderFromLight,
......@@ -264,13 +268,13 @@ class DistantLight : public LightBase {
bool allowIncompletePDF) const {
Vector3f wi = Normalize(renderFromLight(Vector3f(0, 0, 1)));
Point3f pOutside = ctx.p() + wi * (2 * sceneRadius);
return LightLiSample(scale * Lemit.Sample(lambda), wi, 1,
return LightLiSample(scale * Lemit->Sample(lambda), wi, 1,
Interaction(pOutside, nullptr));
}
private:
// DistantLight Private Members
DenselySampledSpectrum Lemit;
const DenselySampledSpectrum *Lemit;
Float scale;
Point3f sceneCenter;
Float sceneRadius;
......@@ -372,12 +376,12 @@ class GoniometricLight : public LightBase {
PBRT_CPU_GPU
SampledSpectrum I(Vector3f w, const SampledWavelengths &lambda) const {
Point2f uv = EqualAreaSphereToSquare(w);
return scale * Iemit.Sample(lambda) * image.LookupNearestChannel(uv, 0);
return scale * Iemit->Sample(lambda) * image.LookupNearestChannel(uv, 0);
}
private:
// GoniometricLight Private Members
DenselySampledSpectrum Iemit;
const DenselySampledSpectrum *Iemit;
Float scale;
Image image;
PiecewiseConstant2D distrib;
......@@ -390,8 +394,7 @@ class DiffuseAreaLight : public LightBase {
DiffuseAreaLight(const Transform &renderFromLight,
const MediumInterface &mediumInterface, Spectrum Le, Float scale,
const Shape shape, FloatTexture alpha, Image image,
const RGBColorSpace *imageColorSpace, bool twoSided,
Allocator alloc);
const RGBColorSpace *imageColorSpace, bool twoSided);
static DiffuseAreaLight *Create(const Transform &renderFromLight, Medium medium,
const ParameterDictionary &parameters,
......@@ -437,7 +440,7 @@ class DiffuseAreaLight : public LightBase {
return scale * spec.Sample(lambda);
} else
return scale * Lemit.Sample(lambda);
return scale * Lemit->Sample(lambda);
}
PBRT_CPU_GPU
......@@ -454,7 +457,7 @@ class DiffuseAreaLight : public LightBase {
FloatTexture alpha;
Float area;
bool twoSided;
DenselySampledSpectrum Lemit;
const DenselySampledSpectrum *Lemit;
Float scale;
Image image;
const RGBColorSpace *imageColorSpace;
......@@ -481,8 +484,7 @@ class DiffuseAreaLight : public LightBase {
class UniformInfiniteLight : public LightBase {
public:
// UniformInfiniteLight Public Methods
UniformInfiniteLight(const Transform &renderFromLight, Spectrum Lemit, Float scale,
Allocator alloc);
UniformInfiniteLight(const Transform &renderFromLight, Spectrum Lemit, Float scale);
void Preprocess(const Bounds3f &sceneBounds) {
sceneBounds.BoundingSphere(&sceneCenter, &sceneRadius);
......@@ -516,7 +518,7 @@ class UniformInfiniteLight : public LightBase {
private:
// UniformInfiniteLight Private Members
DenselySampledSpectrum Lemit;
const DenselySampledSpectrum *Lemit;
Float scale;
Point3f sceneCenter;
Float sceneRadius;
......@@ -716,8 +718,8 @@ class PortalImageInfiniteLight : public LightBase {
class SpotLight : public LightBase {
public:
// SpotLight Public Methods
SpotLight(const Transform &renderFromLight, const MediumInterface &m, Spectrum I,
Float scale, Float totalWidth, Float falloffStart, Allocator alloc);
SpotLight(const Transform &renderFromLight, const MediumInterface &m,
Spectrum I, Float scale, Float totalWidth, Float falloffStart);
static SpotLight *Create(const Transform &renderFromLight, Medium medium,
const ParameterDictionary &parameters,
......@@ -766,7 +768,7 @@ class SpotLight : public LightBase {
private:
// SpotLight Private Members
DenselySampledSpectrum Iemit;
const DenselySampledSpectrum *Iemit;
Float scale, cosFalloffStart, cosFalloffEnd;
};
......
......@@ -24,7 +24,7 @@ TEST(SpotLight, Power) {
static ConstantSpectrum I(10.);
Transform id;
SpotLight light(id, MediumInterface(), &I, 1.f /* scale */, 60 /* total width */,
40 /* falloff start */, Allocator());
40 /* falloff start */);
SampledWavelengths lambda = SampledWavelengths::SampleUniform(0.5);
SampledSpectrum phi = light.Phi(lambda);
......@@ -49,8 +49,7 @@ TEST(SpotLight, Sampling) {
Transform id;
for (auto ws : widthStart) {
SpotLight light(id, MediumInterface(), &I, 1.f /* scale */,
ws[0] /* total width */, ws[1] /* falloff start */,
Allocator());
ws[0] /* total width */, ws[1] /* falloff start */);
RNG rng;
for (int i = 0; i < 100; ++i) {
......
......@@ -27,7 +27,7 @@ TEST(BVHLightSampling, OneSpot) {
ConstantSpectrum one(1.f);
lights.push_back(new SpotLight(id, MediumInterface(), &one, 1.f /* scale */,
45.f /* total width */,
44.f /* falloff start */, Allocator()));
44.f /* falloff start */));
BVHLightSampler distrib(lights, Allocator());
RNG rng;
......@@ -74,8 +74,7 @@ TEST(BVHLightSampling, Point) {
// Random point in [-5, 5]
Vector3f p{Lerp(rng.Uniform<Float>(), -5, 5), Lerp(rng.Uniform<Float>(), -5, 5),
Lerp(rng.Uniform<Float>(), -5, 5)};
lights.push_back(
new PointLight(Translate(p), MediumInterface(), &one, 1.f, Allocator()));
lights.push_back(new PointLight(Translate(p), MediumInterface(), &one, 1.f));
lightToIndex[lights.back()] = i;
}
BVHLightSampler distrib(lights, Allocator());
......@@ -126,7 +125,7 @@ TEST(BVHLightSampling, PointVaryPower) {
lightSpectra.push_back(std::make_unique<ConstantSpectrum>(lightPower.back()));
sumPower += lightPower.back();
lights.push_back(new PointLight(Translate(p), MediumInterface(),
lightSpectra.back().get(), 1.f, Allocator()));
lightSpectra.back().get(), 1.f));
lightToIndex[lights.back()] = i;
}
BVHLightSampler distrib(lights, Allocator());
......@@ -208,8 +207,7 @@ TEST(BVHLightSampling, OneTri) {
std::vector<Light> lights;
ConstantSpectrum one(1.f);
lights.push_back(new DiffuseAreaLight(id, MediumInterface(), &one, 1.f, tris[0],
nullptr, Image(), nullptr, false /* two sided */,
Allocator()));
nullptr, Image(), nullptr, false /* two sided */));
BVHLightSampler distrib(lights, Allocator());
......@@ -259,7 +257,7 @@ static std::tuple<std::vector<Light>, std::vector<Shape>> randomLights(
static Transform id;
lights.push_back(alloc.new_object<DiffuseAreaLight>(
id, MediumInterface(), alloc.new_object<ConstantSpectrum>(r()), 1.f,
tris[0], nullptr, Image(), nullptr, false /* two sided */, Allocator()));
tris[0], nullptr, Image(), nullptr, false /* two sided */));
allTris.push_back(tris[0]);
}
......@@ -270,7 +268,7 @@ static std::tuple<std::vector<Light>, std::vector<Shape>> randomLights(
Lerp(rng.Uniform<Float>(), -5, 5)};
lights.push_back(new PointLight(Translate(p), MediumInterface(),
alloc.new_object<ConstantSpectrum>(r()),
1.f, Allocator()));
1.f));
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册