diff --git a/data/tests/test_luminaire.xml b/data/tests/test_luminaire.xml index 8b8f7429..be906004 100644 --- a/data/tests/test_luminaire.xml +++ b/data/tests/test_luminaire.xml @@ -3,5 +3,8 @@ testcase 'test_chisquare' --> - + + + + diff --git a/include/mitsuba/render/luminaire.h b/include/mitsuba/render/luminaire.h index 070f05d6..eb96afc6 100644 --- a/include/mitsuba/render/luminaire.h +++ b/include/mitsuba/render/luminaire.h @@ -110,7 +110,7 @@ public: Spectrum value; /// Area probability density - Float pdevalArea; + Float pdfArea; /// Directional probability density (wrt. solid angle) Float pdfDir; diff --git a/include/mitsuba/render/shape.h b/include/mitsuba/render/shape.h index 033e218d..bd4c7d0d 100644 --- a/include/mitsuba/render/shape.h +++ b/include/mitsuba/render/shape.h @@ -292,7 +292,7 @@ public: * Return the probability density of sampling the * given point using sampleArea() */ - virtual Float pdevalArea(const ShapeSamplingRecord &sRec) const; + virtual Float pdfArea(const ShapeSamplingRecord &sRec) const; /** * \brief Sample a point on the shape and return the associated diff --git a/include/mitsuba/render/trimesh.h b/include/mitsuba/render/trimesh.h index 16a14fcf..a61cc41d 100644 --- a/include/mitsuba/render/trimesh.h +++ b/include/mitsuba/render/trimesh.h @@ -153,7 +153,7 @@ public: * \brief Return the probability density of sampling the * given point using \ref sampleArea() */ - Float pdevalArea(const ShapeSamplingRecord &sRec) const; + Float pdfArea(const ShapeSamplingRecord &sRec) const; //! @} // ============================================================= diff --git a/src/librender/luminaire.cpp b/src/librender/luminaire.cpp index 1f0d395b..34bb0a99 100644 --- a/src/librender/luminaire.cpp +++ b/src/librender/luminaire.cpp @@ -109,7 +109,7 @@ std::string EmissionRecord::toString() const { << " sRec = " << indent(sRec.toString()) << "," << std::endl << " d = " << d.toString() << "," << std::endl << " value = " << value.toString() << "," << std::endl - << " pdevalArea = " << pdevalArea << "," << std::endl + << " pdfArea = " << pdfArea << "," << std::endl << " pdfDir = " << pdfDir << "," << std::endl << " luminaire = " << ((luminaire == NULL ) ? "null" : indent(((Object *) luminaire)->toString()).c_str()) << std::endl << "]"; diff --git a/src/librender/scene.cpp b/src/librender/scene.cpp index 7a218b47..af577b72 100644 --- a/src/librender/scene.cpp +++ b/src/librender/scene.cpp @@ -521,11 +521,11 @@ void Scene::sampleEmission(EmissionRecord &eRec, Point2 &sample1, Point2 &sample size_t index = m_luminairePDF.sampleReuse(sample1.x, lumPdf); const Luminaire *luminaire = m_luminaires[index]; luminaire->sampleEmission(eRec, sample1, sample2); - eRec.pdevalArea *= lumPdf; + eRec.pdfArea *= lumPdf; eRec.luminaire = luminaire; Float cosTheta = (eRec.luminaire->getType() & Luminaire::EOnSurface) ? absDot(eRec.sRec.n, eRec.d) : 1; - eRec.value *= cosTheta / (eRec.pdevalArea * eRec.pdfDir); + eRec.value *= cosTheta / (eRec.pdfArea * eRec.pdfDir); } void Scene::sampleEmissionArea(EmissionRecord &eRec, Point2 &sample) const { @@ -533,7 +533,7 @@ void Scene::sampleEmissionArea(EmissionRecord &eRec, Point2 &sample) const { size_t index = m_luminairePDF.sampleReuse(sample.x, lumPdf); const Luminaire *luminaire = m_luminaires[index]; luminaire->sampleEmissionArea(eRec, sample); - eRec.pdevalArea *= lumPdf; + eRec.pdfArea *= lumPdf; eRec.luminaire = luminaire; } @@ -548,7 +548,7 @@ void Scene::pdfEmission(EmissionRecord &eRec, bool delta) const { const Float fraction = luminance / m_luminairePDF.getOriginalSum(); luminaire->pdfEmission(eRec, delta); - eRec.pdevalArea *= fraction; + eRec.pdfArea *= fraction; } void Scene::addChild(const std::string &name, ConfigurableObject *child) { diff --git a/src/librender/shape.cpp b/src/librender/shape.cpp index 56a268f2..4c4b8712 100644 --- a/src/librender/shape.cpp +++ b/src/librender/shape.cpp @@ -65,11 +65,11 @@ AABB Shape::getClippedAABB(const AABB &box) const { Float Shape::sampleSolidAngle(ShapeSamplingRecord &sRec, const Point &from, const Point2 &sample) const { /* Turns the area sampling routine into one that samples wrt. solid angles */ - Float pdevalArea = sampleArea(sRec, sample); + Float pdfArea = sampleArea(sRec, sample); Vector lumToPoint = from - sRec.p; Float distSquared = lumToPoint.lengthSquared(), dp = dot(lumToPoint, sRec.n); if (dp > 0) - return pdevalArea * distSquared * std::sqrt(distSquared) / dp; + return pdfArea * distSquared * std::sqrt(distSquared) / dp; else return 0.0f; } @@ -79,7 +79,7 @@ Float Shape::pdfSolidAngle(const ShapeSamplingRecord &sRec, const Point &from) c Vector lumToPoint = from - sRec.p; Float distSquared = lumToPoint.lengthSquared(); Float invDP = std::max((Float) 0, std::sqrt(distSquared) / dot(lumToPoint, sRec.n)); - return pdevalArea(sRec) * distSquared * invDP; + return pdfArea(sRec) * distSquared * invDP; } void Shape::addChild(const std::string &name, ConfigurableObject *child) { @@ -167,8 +167,8 @@ Float Shape::sampleArea(ShapeSamplingRecord &sRec, return 0.0f; } -Float Shape::pdevalArea(const ShapeSamplingRecord &sRec) const { - Log(EError, "%s::pdevalArea(): Not implemented!", +Float Shape::pdfArea(const ShapeSamplingRecord &sRec) const { + Log(EError, "%s::pdfArea(): Not implemented!", getClass()->getName().c_str()); return 0.0f; } diff --git a/src/librender/trimesh.cpp b/src/librender/trimesh.cpp index 86e0fd8e..5d0fd881 100644 --- a/src/librender/trimesh.cpp +++ b/src/librender/trimesh.cpp @@ -259,7 +259,7 @@ AABB TriMesh::getAABB() const { return m_aabb; } -Float TriMesh::pdevalArea(const ShapeSamplingRecord &sRec) const { +Float TriMesh::pdfArea(const ShapeSamplingRecord &sRec) const { return m_invSurfaceArea; } diff --git a/src/librender/vpl.cpp b/src/librender/vpl.cpp index dd3dcbe9..270a63db 100644 --- a/src/librender/vpl.cpp +++ b/src/librender/vpl.cpp @@ -81,7 +81,7 @@ size_t generateVPLs(const Scene *scene, Random *random, /* Sample an emitted particle */ scene->sampleEmissionArea(eRec, areaSample); - weight = eRec.value / eRec.pdevalArea; + weight = eRec.value / eRec.pdfArea; VPL lumVPL(ELuminaireVPL, weight); lumVPL.its.p = eRec.sRec.p; lumVPL.its.shFrame = (eRec.luminaire->getType() & Luminaire::EOnSurface) diff --git a/src/luminaires/area.cpp b/src/luminaires/area.cpp index d9d175ee..86f55ee6 100644 --- a/src/luminaires/area.cpp +++ b/src/luminaires/area.cpp @@ -84,7 +84,7 @@ public: void sampleEmission(EmissionRecord &eRec, const Point2 &sample1, const Point2 &sample2) const { - eRec.pdevalArea = m_shape->sampleArea(eRec.sRec, sample1); + eRec.pdfArea = m_shape->sampleArea(eRec.sRec, sample1); Vector wo = squareToHemispherePSA(sample2); eRec.pdfDir = Frame::cosTheta(wo) * INV_PI; eRec.d = Frame(eRec.sRec.n).toWorld(wo); @@ -92,7 +92,7 @@ public: } void sampleEmissionArea(EmissionRecord &eRec, const Point2 &sample) const { - eRec.pdevalArea = m_shape->sampleArea(eRec.sRec, sample); + eRec.pdfArea = m_shape->sampleArea(eRec.sRec, sample); eRec.value = m_intensity * M_PI; } @@ -122,7 +122,7 @@ public: else { eRec.pdfDir = 0; } - eRec.pdevalArea = delta ? 0.0f : m_shape->pdevalArea(eRec.sRec); + eRec.pdfArea = delta ? 0.0f : m_shape->pdfArea(eRec.sRec); } void setParent(ConfigurableObject *parent) { diff --git a/src/luminaires/collimated.cpp b/src/luminaires/collimated.cpp index e3c161ac..1224206c 100644 --- a/src/luminaires/collimated.cpp +++ b/src/luminaires/collimated.cpp @@ -80,7 +80,7 @@ public: Point2 posOnDisk = squareToDiskConcentric(sample1) * m_radius; eRec.sRec.p = m_luminaireToWorld(Point(posOnDisk.x, posOnDisk.y, 0)); eRec.d = m_direction; - eRec.pdevalArea = m_invSurfaceArea; + eRec.pdfArea = m_invSurfaceArea; eRec.pdfDir = 1; eRec.value = m_intensity; } @@ -88,7 +88,7 @@ public: void sampleEmissionArea(EmissionRecord &eRec, const Point2 &sample) const { Point2 posOnDisk = squareToDiskConcentric(sample) * m_radius; eRec.sRec.p = m_luminaireToWorld(Point(posOnDisk.x, posOnDisk.y, 0)); - eRec.pdevalArea = m_invSurfaceArea; + eRec.pdfArea = m_invSurfaceArea; eRec.value = m_intensity; } @@ -107,7 +107,7 @@ public: } void pdfEmission(EmissionRecord &eRec, bool delta) const { - eRec.pdevalArea = delta ? 0.0f : m_invSurfaceArea; + eRec.pdfArea = delta ? 0.0f : m_invSurfaceArea; eRec.pdfDir = delta ? 1.0f : 0.0f; eRec.value = m_intensity; } diff --git a/src/luminaires/constant.cpp b/src/luminaires/constant.cpp index 926ce19b..653799fd 100644 --- a/src/luminaires/constant.cpp +++ b/src/luminaires/constant.cpp @@ -114,12 +114,12 @@ public: if (length == 0) { eRec.value = Spectrum(0.0f); - eRec.pdevalArea = eRec.pdfDir = 1.0f; + eRec.pdfArea = eRec.pdfDir = 1.0f; return; } eRec.d /= length; - eRec.pdevalArea = m_invSurfaceArea; + eRec.pdfArea = m_invSurfaceArea; eRec.pdfDir = INV_PI * dot(eRec.sRec.n, eRec.d); eRec.value = m_intensity; } @@ -133,7 +133,7 @@ public: Vector d = squareToSphere(sample); eRec.sRec.p = m_bsphere.center + d * radius; eRec.sRec.n = Normal(-d); - eRec.pdevalArea = 1.0f / (4 * M_PI * radius * radius); + eRec.pdfArea = 1.0f / (4 * M_PI * radius * radius); eRec.value = m_intensity * M_PI; } @@ -162,7 +162,7 @@ public: eRec.pdfDir = delta ? 0.0f : INV_PI * dp; else eRec.pdfDir = 0.0f; - eRec.pdevalArea = delta ? 0.0f : m_invSurfaceArea; + eRec.pdfArea = delta ? 0.0f : m_invSurfaceArea; } bool createEmissionRecord(EmissionRecord &eRec, const Ray &ray) const { @@ -177,7 +177,7 @@ public: eRec.sRec.p = ray(nearHit); eRec.sRec.n = normalize(m_bsphere.center - eRec.sRec.p); eRec.d = -ray.d; - eRec.pdevalArea = m_invSurfaceArea; + eRec.pdfArea = m_invSurfaceArea; eRec.pdfDir = INV_PI * dot(eRec.sRec.n, eRec.d); eRec.value = m_intensity; eRec.luminaire = this; diff --git a/src/luminaires/directional.cpp b/src/luminaires/directional.cpp index 397acd7a..df1dbb70 100644 --- a/src/luminaires/directional.cpp +++ b/src/luminaires/directional.cpp @@ -94,7 +94,7 @@ public: Point2 posOnDisk = squareToDiskConcentric(sample1) * m_diskRadius; eRec.sRec.p = m_diskOrigin + Frame(m_direction).toWorld(Vector(posOnDisk.x, posOnDisk.y, 0)); eRec.d = m_direction; - eRec.pdevalArea = m_invSurfaceArea; + eRec.pdfArea = m_invSurfaceArea; eRec.pdfDir = 1; eRec.value = m_intensity; } @@ -102,7 +102,7 @@ public: void sampleEmissionArea(EmissionRecord &eRec, const Point2 &sample) const { Point2 posOnDisk = squareToDiskConcentric(sample) * m_diskRadius; eRec.sRec.p = m_diskOrigin + Frame(m_direction).toWorld(Vector(posOnDisk.x, posOnDisk.y, 0)); - eRec.pdevalArea = m_invSurfaceArea; + eRec.pdfArea = m_invSurfaceArea; eRec.value = m_intensity; } @@ -122,7 +122,7 @@ public: } void pdfEmission(EmissionRecord &eRec, bool delta) const { - eRec.pdevalArea = delta ? 0.0f : m_invSurfaceArea; + eRec.pdfArea = delta ? 0.0f : m_invSurfaceArea; eRec.pdfDir = delta ? 1.0f : 0.0f; eRec.value = m_intensity; } diff --git a/src/luminaires/envmap.cpp b/src/luminaires/envmap.cpp index 02d06142..aafc5a79 100644 --- a/src/luminaires/envmap.cpp +++ b/src/luminaires/envmap.cpp @@ -223,12 +223,12 @@ public: if (length == 0) { eRec.value = Spectrum(0.0f); - eRec.pdevalArea = eRec.pdfDir = 1.0f; + eRec.pdfArea = eRec.pdfDir = 1.0f; return; } eRec.d /= length; - eRec.pdevalArea = m_invSurfaceArea; + eRec.pdfArea = m_invSurfaceArea; eRec.pdfDir = INV_PI * dot(eRec.sRec.n, eRec.d); eRec.value = Le(-eRec.d); } @@ -238,7 +238,7 @@ public: Vector d = squareToSphere(sample); eRec.sRec.p = m_bsphere.center + d * m_bsphere.radius; eRec.sRec.n = Normal(-d); - eRec.pdevalArea = 1.0f / (4 * M_PI * m_bsphere.radius * m_bsphere.radius); + eRec.pdfArea = 1.0f / (4 * M_PI * m_bsphere.radius * m_bsphere.radius); eRec.value = Spectrum(M_PI); } else { /* Preview mode, which is more suitable for VPL-based rendering: approximate @@ -247,7 +247,7 @@ public: Vector d = squareToSphere(sample); eRec.sRec.p = m_bsphere.center + d * radius; eRec.sRec.n = Normal(-d); - eRec.pdevalArea = 1.0f / (4 * M_PI * radius * radius); + eRec.pdfArea = 1.0f / (4 * M_PI * radius * radius); eRec.value = Le(d) * M_PI; } } @@ -280,7 +280,7 @@ public: eRec.pdfDir = delta ? 0.0f : INV_PI * dp; else eRec.pdfDir = 0; - eRec.pdevalArea = delta ? 0.0f : m_invSurfaceArea; + eRec.pdfArea = delta ? 0.0f : m_invSurfaceArea; } Spectrum evalDirection(const EmissionRecord &eRec) const { @@ -306,7 +306,7 @@ public: eRec.type = EmissionRecord::ENormal; eRec.sRec.p = ray(nearHit); eRec.sRec.n = normalize(m_bsphere.center - eRec.sRec.p); - eRec.pdevalArea = m_invSurfaceArea; + eRec.pdfArea = m_invSurfaceArea; eRec.pdfDir = INV_PI * dot(eRec.sRec.n, eRec.d); eRec.d = -ray.d; eRec.value = Le(ray.d); diff --git a/src/luminaires/point.cpp b/src/luminaires/point.cpp index e13a572b..c519a76b 100644 --- a/src/luminaires/point.cpp +++ b/src/luminaires/point.cpp @@ -68,13 +68,13 @@ public: eRec.sRec.p = m_position; eRec.d = squareToSphere(sample2); eRec.pdfDir = 1.0f / (4 * M_PI); - eRec.pdevalArea = 1; + eRec.pdfArea = 1; eRec.value = m_intensity; } void sampleEmissionArea(EmissionRecord &eRec, const Point2 &sample) const { eRec.sRec.p = m_position; - eRec.pdevalArea = 1; + eRec.pdfArea = 1; eRec.value = m_intensity * (4*M_PI); } @@ -86,7 +86,7 @@ public: void pdfEmission(EmissionRecord &eRec, bool delta) const { eRec.pdfDir = delta ? 0.0f : 1.0f / (4 * M_PI); - eRec.pdevalArea = delta ? 1.0f : 0.0f; + eRec.pdfArea = delta ? 1.0f : 0.0f; } Spectrum evalArea(const EmissionRecord &eRec) const { diff --git a/src/luminaires/sky.cpp b/src/luminaires/sky.cpp index 1c5a4fce..5b801b6f 100644 --- a/src/luminaires/sky.cpp +++ b/src/luminaires/sky.cpp @@ -411,12 +411,12 @@ public: if (length == 0) { eRec.value = Spectrum(0.0f); - eRec.pdevalArea = eRec.pdfDir = 1.0f; + eRec.pdfArea = eRec.pdfDir = 1.0f; return; } eRec.d /= length; - eRec.pdevalArea = 1.0f / (4 * M_PI * m_bsphere.radius * m_bsphere.radius); + eRec.pdfArea = 1.0f / (4 * M_PI * m_bsphere.radius * m_bsphere.radius); eRec.pdfDir = INV_PI * dot(eRec.sRec.n, eRec.d); eRec.value = Le(-eRec.d); } @@ -426,7 +426,7 @@ public: Vector d = squareToSphere(sample); eRec.sRec.p = m_bsphere.center + d * m_bsphere.radius; eRec.sRec.n = Normal(-d); - eRec.pdevalArea = 1.0f / (4 * M_PI * m_bsphere.radius * m_bsphere.radius); + eRec.pdfArea = 1.0f / (4 * M_PI * m_bsphere.radius * m_bsphere.radius); eRec.value = Spectrum(M_PI); } else { /* Preview mode, which is more suitable for VPL-based rendering: approximate @@ -435,7 +435,7 @@ public: Vector d = squareToSphere(sample); eRec.sRec.p = m_bsphere.center + d * radius; eRec.sRec.n = Normal(-d); - eRec.pdevalArea = 1.0f / (4 * M_PI * radius * radius); + eRec.pdfArea = 1.0f / (4 * M_PI * radius * radius); eRec.value = Le(d) * M_PI; } } diff --git a/src/luminaires/spot.cpp b/src/luminaires/spot.cpp index 219fa0d5..bd0c0116 100644 --- a/src/luminaires/spot.cpp +++ b/src/luminaires/spot.cpp @@ -123,13 +123,13 @@ public: eRec.sRec.p = m_position; m_luminaireToWorld(squareToCone(m_cosCutoffAngle, sample2), eRec.d); eRec.pdfDir = squareToConePdf(m_cosCutoffAngle); - eRec.pdevalArea = 1; + eRec.pdfArea = 1; eRec.value = falloffCurve(eRec.d); } void sampleEmissionArea(EmissionRecord &eRec, const Point2 &sample) const { eRec.sRec.p = m_position; - eRec.pdevalArea = 1; + eRec.pdfArea = 1; eRec.value = m_intensity; } @@ -144,7 +144,7 @@ public: eRec.pdfDir = 0; else eRec.pdfDir = delta ? 0.0f : squareToConePdf(m_cosCutoffAngle); - eRec.pdevalArea = delta ? 1.0f : 0.0f; + eRec.pdfArea = delta ? 1.0f : 0.0f; } Spectrum evalDirection(const EmissionRecord &eRec) const { diff --git a/src/shapes/sphere.cpp b/src/shapes/sphere.cpp index 75f2a1a8..738e337a 100644 --- a/src/shapes/sphere.cpp +++ b/src/shapes/sphere.cpp @@ -179,7 +179,7 @@ public: return 1.0f / (4*M_PI*m_radius*m_radius); } - Float pdevalArea(const ShapeSamplingRecord &sRec) const { + Float pdfArea(const ShapeSamplingRecord &sRec) const { return 1.0f / (4*M_PI*m_radius*m_radius); } diff --git a/src/tests/test_chisquare.cpp b/src/tests/test_chisquare.cpp index 3d7e727c..7e80a16e 100644 --- a/src/tests/test_chisquare.cpp +++ b/src/tests/test_chisquare.cpp @@ -47,8 +47,8 @@ class TestChiSquare : public TestCase { public: MTS_BEGIN_TESTCASE() MTS_DECLARE_TEST(test03_Luminaire) - MTS_DECLARE_TEST(test01_BSDF) - MTS_DECLARE_TEST(test02_PhaseFunction) +// MTS_DECLARE_TEST(test01_BSDF) +// MTS_DECLARE_TEST(test02_PhaseFunction) MTS_END_TESTCASE() /** @@ -307,17 +307,16 @@ public: : m_luminaire(luminaire), m_sampler(sampler) { } boost::tuple generateSample() { - EmissionRecord eRec; - #if defined(MTS_DEBUG_FP) enableFPExceptions(); #endif - /* Check the various sampling routines for agreement amongst each other */ - m_luminaire->sampleEmission(eRec, m_sampler->next2D(), m_sampler->next2D()); - Spectrum value = eRec.value; - Spectrum value2 = - m_luminaire->evalArea(eRec) * m_luminaire->evalDirection(eRec); + LuminaireSamplingRecord lRec; + m_luminaire->sample(Point(0.0f), lRec, m_sampler->next2D()); + Spectrum value = lRec.value / lRec.pdf; + Float pdf = m_luminaire->pdf(Point(0.0f), lRec, false); + Spectrum Le = m_luminaire->Le(Ray(Point(0.0f), -lRec.d, 0.0f)); + Spectrum value2 = Le/pdf; bool mismatch = false; for (int i=0; ipdfEmission(eRec, false); + LuminaireSamplingRecord lRec; + lRec.d = d; + Float result = m_luminaire->pdf(Point(0.0f), lRec, false); #if defined(MTS_DEBUG_FP) disableFPExceptions(); #endif - return eRec.pdfDir; + return result; } private: @@ -540,8 +539,9 @@ public: void test03_Luminaire() { /* Load a set of luminaire instances to be tested from the following XML file */ ref scene = loadScene("data/tests/test_luminaire.xml"); + scene->initialize(); - const std::vector objects = scene->getReferencedObjects(); + const std::vector luminaires = scene->getLuminaires(); size_t thetaBins = 10, wiSamples = 20, failureCount = 0, testCount = 0; ref sampler = static_cast (PluginManager::getInstance()-> createObject(MTS_CLASS(Sampler), Properties("independent"))); @@ -549,11 +549,8 @@ public: ProgressReporter *progress = new ProgressReporter("Checking", wiSamples, NULL); Log(EInfo, "Verifying luminaire sampling routines .."); - for (size_t i=0; igetClass()->derivesFrom(MTS_CLASS(Luminaire))) - continue; - - const Luminaire *luminaire = static_cast(objects[i]); + for (size_t i=0; itoString().c_str()); Log(EInfo, "Checking the model for %i incident directions", wiSamples);