From 0230c6fbe7149beac61cf158052e36983c95c379 Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Sun, 17 Jul 2011 17:18:58 +0200 Subject: [PATCH] switched to a new BSDFQueryRecord constructor, which encapsulates the assumption that a sampler instance is always available when sampling the model --- include/mitsuba/render/bsdf.h | 15 ++++++--- include/mitsuba/render/integrator.h | 31 ++++++++++--------- include/mitsuba/render/records.inl | 4 +-- src/bsdfs/bump.cpp | 5 ++- src/bsdfs/roughconductor.cpp | 1 - src/bsdfs/roughplastic.cpp | 1 - src/integrators/direct/direct.cpp | 4 +-- src/integrators/path/path.cpp | 3 +- src/integrators/path/volpath.cpp | 4 +-- src/integrators/path/volpath_simple.cpp | 3 +- src/integrators/photonmapper/photonmapper.cpp | 4 +-- src/integrators/photonmapper/ppm.cpp | 2 +- src/integrators/photonmapper/sppm.cpp | 3 +- src/librender/bsdf.cpp | 3 +- src/librender/particleproc.cpp | 3 +- src/librender/vpl.cpp | 3 +- src/tests/test_chisquare.cpp | 15 ++------- 17 files changed, 43 insertions(+), 61 deletions(-) diff --git a/include/mitsuba/render/bsdf.h b/include/mitsuba/render/bsdf.h index 11cd5860..a2b8cad8 100644 --- a/include/mitsuba/render/bsdf.h +++ b/include/mitsuba/render/bsdf.h @@ -49,12 +49,17 @@ public: * * \param its * An reference to the underlying intersection record - * \param typeMask - * The list of components that should be sampled + * + * \param sampler + * A source of (pseudo-) random numbers. Note that this sampler + * is only used when the scattering model for some reason needs + * more than the two unformly distributed numbers supplied in + * the \ref BSDF::sample() methods + * * \param quantity * The transported quantity (\ref ERadiance or \ref EImportance) */ - explicit inline BSDFQueryRecord(const Intersection &its, + explicit inline BSDFQueryRecord(const Intersection &its, Sampler *sampler, ETransportQuantity quantity = ERadiance); /** @@ -112,8 +117,8 @@ public: * Some BSDF implementations can significantly improve * the quality of their importance sampling routines * when having access to extra random numbers. This - * attribute provides a means of providing this capability - * to the BSDF. + * attribute provides a means of providing this + * capability to the BSDF. */ Sampler *sampler; diff --git a/include/mitsuba/render/integrator.h b/include/mitsuba/render/integrator.h index 0eea049c..7a7a48e0 100644 --- a/include/mitsuba/render/integrator.h +++ b/include/mitsuba/render/integrator.h @@ -115,53 +115,54 @@ public: /// List of suported query types. These can be combined by a binary OR. enum ERadianceQuery { /// Emitted radiance from a luminaire intersected by the ray - EEmittedRadiance = 0x0001, + EEmittedRadiance = 0x0001, /// Emitted radiance from a subsurface integrator */ - ESubsurfaceRadiance = 0x0002, + ESubsurfaceRadiance = 0x0002, /// Direct (surface) radiance */ - EDirectSurfaceRadiance = 0x0004, + EDirectSurfaceRadiance = 0x0004, /*! \brief Indirect (surface) radiance, where the last bounce did not go through a Dirac delta BSDF */ - EIndirectSurfaceRadiance = 0x0008, + EIndirectSurfaceRadiance = 0x0008, /*! \brief Indirect (surface) radiance, where the last bounce went through a Dirac delta BSDF */ - ECausticRadiance = 0x0010, + ECausticRadiance = 0x0010, /// In-scattered radiance due to volumetric scattering (direct) - EDirectMediumRadiance = 0x0020, + EDirectMediumRadiance = 0x0020, /// In-scattered radiance due to volumetric scattering (indirect) - EIndirectMediumRadiance = 0x0040, + EIndirectMediumRadiance = 0x0040, /// Distance to the next surface intersection - EDistance = 0x0080, + EDistance = 0x0080, /*! \brief Store an opacity value, which is equal to 1 when a shape was intersected and 0 when the ray passes through empty space. When there is a participating medium, it can also take on fractional values. */ - EOpacity = 0x0100, + EOpacity = 0x0100, /*! \brief A ray intersection may need to be performed. This can be set to zero if the caller has already provided the intersection */ - EIntersection = 0x0200, + EIntersection = 0x0200, /* Radiance from volumes */ - EVolumeRadiance = EDirectMediumRadiance | EIndirectMediumRadiance, + EVolumeRadiance = EDirectMediumRadiance | EIndirectMediumRadiance, /// Radiance query without emitted radiance, ray intersection required - ERadianceNoEmission = ESubsurfaceRadiance | EDirectSurfaceRadiance | EIndirectSurfaceRadiance - | ECausticRadiance | EDirectMediumRadiance | EIndirectMediumRadiance | EIntersection, + ERadianceNoEmission = ESubsurfaceRadiance | EDirectSurfaceRadiance + | EIndirectSurfaceRadiance | ECausticRadiance | EDirectMediumRadiance + | EIndirectMediumRadiance | EIntersection, /// Default radiance query, ray intersection required - ERadiance = ERadianceNoEmission | EEmittedRadiance, + ERadiance = ERadianceNoEmission | EEmittedRadiance, /// Radiance + opacity - ECameraRay = ERadiance | EOpacity + ECameraRay = ERadiance | EOpacity }; /// Construct an invalid radiance query record diff --git a/include/mitsuba/render/records.inl b/include/mitsuba/render/records.inl index 1c0cc1ce..8d598715 100644 --- a/include/mitsuba/render/records.inl +++ b/include/mitsuba/render/records.inl @@ -21,8 +21,8 @@ MTS_NAMESPACE_BEGIN -inline BSDFQueryRecord::BSDFQueryRecord(const Intersection &its, ETransportQuantity quantity) - : its(its), sampler(NULL), wi(its.wi), quantity(quantity), +inline BSDFQueryRecord::BSDFQueryRecord(const Intersection &its, Sampler *sampler, ETransportQuantity quantity) + : its(its), sampler(sampler), wi(its.wi), quantity(quantity), typeMask(BSDF::EAll), sampledType(0), component(-1), sampledComponent(-1) { } diff --git a/src/bsdfs/bump.cpp b/src/bsdfs/bump.cpp index c846e04a..0af2362c 100644 --- a/src/bsdfs/bump.cpp +++ b/src/bsdfs/bump.cpp @@ -195,9 +195,8 @@ public: Intersection perturbed; perturbIntersection(its, perturbed); - BSDFQueryRecord perturbedQuery(perturbed, bRec.quantity); + BSDFQueryRecord perturbedQuery(perturbed, bRec.sampler, bRec.quantity); perturbedQuery.wi = perturbed.toLocal(its.toWorld(bRec.wi)); - perturbedQuery.sampler = bRec.sampler; perturbedQuery.typeMask = bRec.typeMask; perturbedQuery.component = bRec.component; Spectrum result = m_nested->sample(perturbedQuery, pdf, sample); @@ -218,7 +217,7 @@ public: Intersection perturbed; perturbIntersection(its, perturbed); - BSDFQueryRecord perturbedQuery(perturbed, bRec.quantity); + BSDFQueryRecord perturbedQuery(perturbed, bRec.sampler, bRec.quantity); perturbedQuery.wi = perturbed.toLocal(its.toWorld(bRec.wi)); perturbedQuery.sampler = bRec.sampler; perturbedQuery.typeMask = bRec.typeMask; diff --git a/src/bsdfs/roughconductor.cpp b/src/bsdfs/roughconductor.cpp index f257fa51..31bbb06d 100644 --- a/src/bsdfs/roughconductor.cpp +++ b/src/bsdfs/roughconductor.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include "microfacet.h" diff --git a/src/bsdfs/roughplastic.cpp b/src/bsdfs/roughplastic.cpp index 6589f768..4ca2d83f 100644 --- a/src/bsdfs/roughplastic.cpp +++ b/src/bsdfs/roughplastic.cpp @@ -17,7 +17,6 @@ */ #include -#include #include #include "microfacet.h" #include "ior.h" diff --git a/src/integrators/direct/direct.cpp b/src/integrators/direct/direct.cpp index 7e4af160..dd88efee 100644 --- a/src/integrators/direct/direct.cpp +++ b/src/integrators/direct/direct.cpp @@ -135,7 +135,6 @@ public: if (scene->sampleLuminaire(its.p, ray.time, lRec, sampleArray[i])) { /* Allocate a record for querying the BSDF */ BSDFQueryRecord bRec(its, its.toLocal(-lRec.d)); - bRec.sampler = rRec.sampler; /* Evaluate BSDF * cos(theta) */ const Spectrum bsdfVal = bsdf->eval(bRec); @@ -167,8 +166,7 @@ public: for (size_t i=0; isample(bRec, bsdfPdf, sampleArray[i]); if (bsdfVal.isZero()) diff --git a/src/integrators/path/path.cpp b/src/integrators/path/path.cpp index f59d631b..e64263b6 100644 --- a/src/integrators/path/path.cpp +++ b/src/integrators/path/path.cpp @@ -131,8 +131,7 @@ public: /* ==================================================================== */ /* Sample BSDF * cos(theta) */ - BSDFQueryRecord bRec(its); - bRec.sampler = rRec.sampler; + BSDFQueryRecord bRec(its, rRec.sampler, ERadiance); Float bsdfPdf; Spectrum bsdfVal = bsdf->sample(bRec, bsdfPdf, rRec.nextSample2D()); if (bsdfVal.isZero()) diff --git a/src/integrators/path/volpath.cpp b/src/integrators/path/volpath.cpp index d800acf8..010428be 100644 --- a/src/integrators/path/volpath.cpp +++ b/src/integrators/path/volpath.cpp @@ -225,7 +225,6 @@ public: /* Allocate a record for querying the BSDF */ BSDFQueryRecord bRec(its, its.toLocal(wo)); - bRec.sampler = rRec.sampler; /* Evaluate BSDF * cos(theta) */ const Spectrum bsdfVal = bsdf->eval(bRec); @@ -252,8 +251,7 @@ public: /* ==================================================================== */ /* Sample BSDF * cos(theta) */ - BSDFQueryRecord bRec(its); - bRec.sampler = rRec.sampler; + BSDFQueryRecord bRec(its, rRec.sampler, ERadiance); Float bsdfPdf; Spectrum bsdfVal = bsdf->sample(bRec, bsdfPdf, rRec.nextSample2D()); if (bsdfVal.isZero()) diff --git a/src/integrators/path/volpath_simple.cpp b/src/integrators/path/volpath_simple.cpp index b5acab22..422b3e99 100644 --- a/src/integrators/path/volpath_simple.cpp +++ b/src/integrators/path/volpath_simple.cpp @@ -183,8 +183,7 @@ public: /* ==================================================================== */ /* Sample BSDF * cos(theta) */ - BSDFQueryRecord bRec(its); - bRec.sampler = rRec.sampler; + BSDFQueryRecord bRec(its, rRec.sampler, ERadiance); Spectrum bsdfVal = bsdf->sample(bRec, rRec.nextSample2D()); if (bsdfVal.isZero()) break; diff --git a/src/integrators/photonmapper/photonmapper.cpp b/src/integrators/photonmapper/photonmapper.cpp index d9bb46f0..8b965b80 100644 --- a/src/integrators/photonmapper/photonmapper.cpp +++ b/src/integrators/photonmapper/photonmapper.cpp @@ -368,7 +368,7 @@ public: int compCount = bsdf->getComponentCount(); for (int i=0; isample(bRec, Point2(0.0f)); if (bsdfVal.isZero()) @@ -388,7 +388,7 @@ public: Float weight = 1 / (Float) m_glossySamples; for (int i=0; isample(bRec, sampleArray[i]); diff --git a/src/integrators/photonmapper/ppm.cpp b/src/integrators/photonmapper/ppm.cpp index a21f8935..5d289e25 100644 --- a/src/integrators/photonmapper/ppm.cpp +++ b/src/integrators/photonmapper/ppm.cpp @@ -246,7 +246,7 @@ public: if ((bsdf->getType(i) & BSDF::EDelta) == 0) continue; /* Sample the BSDF and recurse */ - BSDFQueryRecord bRec(p.its); + BSDFQueryRecord bRec(p.its, sampler); bRec.component = i; Spectrum bsdfVal = bsdf->sample(bRec, Point2(0.0f)); if (bsdfVal.isZero()) diff --git a/src/integrators/photonmapper/sppm.cpp b/src/integrators/photonmapper/sppm.cpp index ebef623c..ac6e8163 100644 --- a/src/integrators/photonmapper/sppm.cpp +++ b/src/integrators/photonmapper/sppm.cpp @@ -237,8 +237,7 @@ public: } else { /* Recurse for dielectric materials and (specific to SPPM): recursive "final gathering" for glossy materials */ - BSDFQueryRecord bRec(gatherPoint.its); - bRec.sampler = sampler; + BSDFQueryRecord bRec(gatherPoint.its, sampler); weight *= bsdf->sample(bRec, sampler->next2D()); if (weight.isZero()) { gatherPoint.depth = -1; diff --git a/src/librender/bsdf.cpp b/src/librender/bsdf.cpp index 9985d736..8c7cb965 100644 --- a/src/librender/bsdf.cpp +++ b/src/librender/bsdf.cpp @@ -62,8 +62,7 @@ void BSDF::configure() { } Spectrum BSDF::getDiffuseReflectance(const Intersection &its) const { - BSDFQueryRecord bRec(its); - bRec.wi = bRec.wo = Vector(0, 0, 1); + BSDFQueryRecord bRec(its, Vector(0, 0, 1), Vector(0, 0, 1)); bRec.typeMask = EDiffuseReflection; return eval(bRec) * M_PI; } diff --git a/src/librender/particleproc.cpp b/src/librender/particleproc.cpp index 52001094..81ee906b 100644 --- a/src/librender/particleproc.cpp +++ b/src/librender/particleproc.cpp @@ -190,8 +190,7 @@ void ParticleTracer::process(const WorkUnit *workUnit, WorkResult *workResult, continue; } - BSDFQueryRecord bRec(its, EImportance); - bRec.sampler = m_sampler; + BSDFQueryRecord bRec(its, m_sampler, EImportance); bsdfVal = bsdf->sample(bRec, m_sampler->next2D()); if (bsdfVal.isZero()) break; diff --git a/src/librender/vpl.cpp b/src/librender/vpl.cpp index 4f4bd686..270a63db 100644 --- a/src/librender/vpl.cpp +++ b/src/librender/vpl.cpp @@ -107,8 +107,7 @@ size_t generateVPLs(const Scene *scene, Random *random, continue; } - BSDFQueryRecord bRec(its, EImportance); - bRec.sampler = sampler; + BSDFQueryRecord bRec(its, sampler, EImportance); bsdfVal = bsdf->sample(bRec, sampler->next2D()); if (bsdfVal.isZero()) break; diff --git a/src/tests/test_chisquare.cpp b/src/tests/test_chisquare.cpp index 373a2697..8a347b73 100644 --- a/src/tests/test_chisquare.cpp +++ b/src/tests/test_chisquare.cpp @@ -108,7 +108,7 @@ public: boost::tuple generateSample() { Point2 sample(m_sampler->next2D()); - BSDFQueryRecord bRec(m_its); + BSDFQueryRecord bRec(m_its, m_fakeSampler); bRec.component = m_component; bRec.wi = m_wi; @@ -118,14 +118,6 @@ public: Float pdfVal, pdfVal2; - /* Only make the sampler available to the BSDF when requested - by the testcase. This allows testing both sampling variants - where applicable: those that can improve by having access to - an arbitrary random number stream vs. those that only use - a single uniform 2D sample */ - - bRec.sampler = m_fakeSampler; - /* Check the various sampling routines for agreement amongst each other */ m_fakeSampler->clear(); @@ -190,11 +182,8 @@ public: } Float pdf(const Vector &wo, EMeasure measure) { - BSDFQueryRecord bRec(m_its); + BSDFQueryRecord bRec(m_its, m_wi, wo); bRec.component = m_component; - bRec.wi = m_wi; - bRec.wo = wo; - bRec.sampler = m_sampler; #if defined(MTS_DEBUG_FP) enableFPExceptions();