diff --git a/data/tests/test_bsdf.xml b/data/tests/test_bsdf.xml index a0add420..9eae929e 100644 --- a/data/tests/test_bsdf.xml +++ b/data/tests/test_bsdf.xml @@ -2,22 +2,6 @@ to be tested for consistency. This is done using the testcase 'test_chisquare' --> - - - - - - - - - - - - - - - @@ -40,6 +24,27 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/bsdfs/conductor.cpp b/src/bsdfs/conductor.cpp index 724bba62..8c16396b 100644 --- a/src/bsdfs/conductor.cpp +++ b/src/bsdfs/conductor.cpp @@ -265,6 +265,7 @@ public: std::string toString() const { std::ostringstream oss; oss << "SmoothConductor[" << endl + << " name = \"" << getName() << "\"," << endl << " eta = " << m_eta.toString() << "," << endl << " k = " << m_k.toString() << "," << endl << " specularReflectance = " << indent(m_specularReflectance->toString()) << endl diff --git a/src/bsdfs/dielectric.cpp b/src/bsdfs/dielectric.cpp index 23f040d6..5422fbeb 100644 --- a/src/bsdfs/dielectric.cpp +++ b/src/bsdfs/dielectric.cpp @@ -477,6 +477,7 @@ public: std::string toString() const { std::ostringstream oss; oss << "SmoothDielectric[" << endl + << " name = \"" << getName() << "\"," << endl << " intIOR = " << m_intIOR << "," << endl << " extIOR = " << m_extIOR << "," << endl << " specularReflectance = " << indent(m_specularReflectance->toString()) << "," << endl diff --git a/src/bsdfs/difftrans.cpp b/src/bsdfs/difftrans.cpp index b334d6df..caae7d38 100644 --- a/src/bsdfs/difftrans.cpp +++ b/src/bsdfs/difftrans.cpp @@ -129,6 +129,7 @@ public: std::string toString() const { std::ostringstream oss; oss << "DiffuseTransmitter[" << endl + << " name = \"" << getName() << "\"," << endl << " transmittance = " << indent(m_transmittance->toString()) << endl << "]"; return oss.str(); diff --git a/src/bsdfs/mixture.cpp b/src/bsdfs/mixture.cpp index 58adb0fd..68b955f9 100644 --- a/src/bsdfs/mixture.cpp +++ b/src/bsdfs/mixture.cpp @@ -37,7 +37,6 @@ public: Log(EError, "No weights were supplied!"); m_weights.resize(weights.size()); - Float totalWeight = 0; char *end_ptr = NULL; for (size_t i=0; i 1) - Log(EWarn, "Energy conservation is violated!"); - if (totalWeight == 0) - Log(EError, "Combined weight must be > 0!"); } MixtureBSDF(Stream *stream, InstanceManager *manager) @@ -91,6 +84,27 @@ public: Log(EError, "BSDF count mismatch: " SIZE_T_FMT " bsdfs, but specified " SIZE_T_FMT " weights", m_bsdfs.size(), m_bsdfs.size()); + Float totalWeight = 0; + for (size_t i=0; i 1) { + std::ostringstream oss; + Float scale = 1.0f / totalWeight; + oss << "The BSDF" << endl << toString() << endl + << "potentially violates energy conservation, since the weights " + << "sum to " << totalWeight << ", which is greater than one! " + << "They will be re-scaled to avoid potential issues. Specify " + << "the parameter ensureEnergyConservation=false to prevent " + << "this from happening."; + Log(EWarn, "%s", oss.str().c_str()); + for (size_t i=0; igetComponentCount(); @@ -239,6 +253,7 @@ public: std::string toString() const { std::ostringstream oss; oss << "MixtureBSDF[" << endl + << " name = \"" << getName() << "\"," << endl << " weights = {"; for (size_t i=0; iclear(); Spectrum f = m_bsdf->sample(bRec, pdfVal, sample); m_fakeSampler->rewind(); Spectrum sampled = m_bsdf->sample(bRec, sample); + EMeasure measure = ESolidAngle; + if (!f.isZero()) + measure = BSDF::getMeasure(bRec.sampledType); + Spectrum f2 = m_bsdf->eval(bRec, measure); + pdfVal2 = m_bsdf->pdf(bRec, measure); - if (f.isZero() || pdfVal == 0) { - if (!sampled.isZero()) - Log(EWarn, "Inconsistency (1): f=%s, pdf=%f, sampled f/pdf=%s, bRec=%s", - f.toString().c_str(), pdfVal, sampled.toString().c_str(), bRec.toString().c_str()); + if (f.isZero() || pdfVal == 0 || pdfVal2 == 0) { + if (!sampled.isZero()) + Log(EWarn, "Inconsistency (1): f=%s, f2=%s, pdf=%f, pdf2=%f, sampled f/pdf=%s, bRec=%s, measure=%i", + f.toString().c_str(), f2.toString().c_str(), pdfVal, pdfVal2, sampled.toString().c_str(), bRec.toString().c_str(), measure); #if defined(MTS_DEBUG_FP) disableFPExceptions(); #endif return boost::make_tuple(bRec.wo, 0.0f, ESolidAngle); } else if (sampled.isZero()) { - if (!f.isZero() && pdfVal != 0) - Log(EWarn, "Inconsistency (2): f=%s, pdf=%f, sampled f/pdf=%s, bRec=%s", - f.toString().c_str(), pdfVal, sampled.toString().c_str(), bRec.toString().c_str()); + if ((!f.isZero() && pdfVal != 0) || (!f2.isZero() && pdfVal2 != 0)) + Log(EWarn, "Inconsistency (2): f=%s, f2=%s, pdf=%f, pdf2=%f, sampled f/pdf=%s, bRec=%s, measure=%i", + f.toString().c_str(), f2.toString().c_str(), pdfVal, pdfVal2, sampled.toString().c_str(), bRec.toString().c_str(), measure); #if defined(MTS_DEBUG_FP) disableFPExceptions(); #endif return boost::make_tuple(bRec.wo, 0.0f, ESolidAngle); } - Spectrum sampled2 = f/pdfVal; - if (!sampled.isValid() || !sampled2.isValid()) { - Log(EWarn, "Ooops: f=%s, pdf=%f, sampled f/pdf=%s, bRec=%s", - f.toString().c_str(), pdfVal, sampled.toString().c_str(), bRec.toString().c_str()); + Spectrum sampled2 = f/pdfVal, evaluated = f2/pdfVal2; + if (!sampled.isValid() || !sampled2.isValid() || !evaluated.isValid()) { + Log(EWarn, "Ooops: f=%s, f2=%s, pdf=%f, pdf2=%f, sampled f/pdf=%s, bRec=%s, measure=%i", + f.toString().c_str(), f2.toString().c_str(), pdfVal, pdfVal2, sampled.toString().c_str(), bRec.toString().c_str(), measure); return boost::make_tuple(bRec.wo, 0.0f, ESolidAngle); } bool mismatch = false; for (int i=0; i ERROR_REQ) // absolute error threshold @@ -168,15 +174,14 @@ public: } if (mismatch) - Log(EWarn, "Potential inconsistency (3): f/pdf=%s, sampled f/pdf=%s", - sampled2.toString().c_str(), sampled.toString().c_str()); - + Log(EWarn, "Potential inconsistency (3): f/pdf=%s (method 1), f/pdf=%s (methdod 2), sampled f/pdf=%s", + sampled2.toString().c_str(), evaluated.toString().c_str(), sampled.toString().c_str()); + #if defined(MTS_DEBUG_FP) disableFPExceptions(); #endif - return boost::make_tuple(bRec.wo, 1.0f, - BSDF::getMeasure(bRec.sampledType)); + return boost::make_tuple(bRec.wo, 1.0f, measure); } Float pdf(const Vector &wo, EMeasure measure) {