switched to a new BSDFQueryRecord constructor, which encapsulates the assumption that a sampler instance is always available when sampling the model

metadata
Wenzel Jakob 2011-07-17 17:18:58 +02:00
parent fad581de2f
commit 0230c6fbe7
17 changed files with 43 additions and 61 deletions

View File

@ -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;

View File

@ -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

View File

@ -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) {
}

View File

@ -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;

View File

@ -18,7 +18,6 @@
#include <mitsuba/core/fresolver.h>
#include <mitsuba/render/bsdf.h>
#include <mitsuba/render/sampler.h>
#include <mitsuba/hw/basicshader.h>
#include "microfacet.h"

View File

@ -17,7 +17,6 @@
*/
#include <mitsuba/render/bsdf.h>
#include <mitsuba/render/sampler.h>
#include <mitsuba/hw/basicshader.h>
#include "microfacet.h"
#include "ior.h"

View File

@ -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; i<numBSDFSamples; ++i) {
/* 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, sampleArray[i]);
if (bsdfVal.isZero())

View File

@ -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())

View File

@ -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())

View File

@ -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;

View File

@ -368,7 +368,7 @@ public:
int compCount = bsdf->getComponentCount();
for (int i=0; i<compCount; i++) {
/* Sample the BSDF and recurse */
BSDFQueryRecord bRec(its);
BSDFQueryRecord bRec(its, rRec.sampler);
bRec.component = i;
Spectrum bsdfVal = bsdf->sample(bRec, Point2(0.0f));
if (bsdfVal.isZero())
@ -388,7 +388,7 @@ public:
Float weight = 1 / (Float) m_glossySamples;
for (int i=0; i<m_glossySamples; ++i) {
BSDFQueryRecord bRec(its);
BSDFQueryRecord bRec(its, rRec.sampler);
bRec.sampler = rRec.sampler;
Spectrum bsdfVal = bsdf->sample(bRec, sampleArray[i]);

View File

@ -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())

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -108,7 +108,7 @@ public:
boost::tuple<Vector, Float, EMeasure> 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();