diff --git a/doc/images/medium_heterogeneous_density_1000.jpg b/doc/images/medium_heterogeneous_density_1000.jpg new file mode 100644 index 00000000..dc0badcf Binary files /dev/null and b/doc/images/medium_heterogeneous_density_1000.jpg differ diff --git a/doc/images/medium_heterogeneous_density_200.jpg b/doc/images/medium_heterogeneous_density_200.jpg new file mode 100644 index 00000000..f177b326 Binary files /dev/null and b/doc/images/medium_heterogeneous_density_200.jpg differ diff --git a/doc/images/medium_heterogeneous_density_40.jpg b/doc/images/medium_heterogeneous_density_40.jpg new file mode 100644 index 00000000..044c482e Binary files /dev/null and b/doc/images/medium_heterogeneous_density_40.jpg differ diff --git a/src/integrators/photonmapper/photonmapper.cpp b/src/integrators/photonmapper/photonmapper.cpp index 98ba423a..d7c01d5d 100644 --- a/src/integrators/photonmapper/photonmapper.cpp +++ b/src/integrators/photonmapper/photonmapper.cpp @@ -184,10 +184,13 @@ public: Log(EDebug, "Global photon map full. Shot " SIZE_T_FMT " particles, excess photons due to parallelism: " SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons()); - m_globalPhotonMap = proc->getPhotonMap(); - m_globalPhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles()); - m_globalPhotonMap->build(); - m_globalPhotonMapID = sched->registerResource(m_globalPhotonMap); + ref globalPhotonMap = proc->getPhotonMap(); + if (globalPhotonMap->isFull()) { + m_globalPhotonMap = globalPhotonMap; + m_globalPhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles()); + m_globalPhotonMap->build(); + m_globalPhotonMapID = sched->registerResource(m_globalPhotonMap); + } } if (m_causticPhotonMap.get() == NULL && m_causticPhotons > 0) { @@ -212,10 +215,13 @@ public: Log(EDebug, "Caustic photon map full. Shot " SIZE_T_FMT " particles, excess photons due to parallelism: " SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons()); - m_causticPhotonMap = proc->getPhotonMap(); - m_causticPhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles()); - m_causticPhotonMap->build(); - m_causticPhotonMapID = sched->registerResource(m_causticPhotonMap); + ref causticPhotonMap = proc->getPhotonMap(); + if (causticPhotonMap->isFull()) { + m_causticPhotonMap = causticPhotonMap; + m_causticPhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles()); + m_causticPhotonMap->build(); + m_causticPhotonMapID = sched->registerResource(m_causticPhotonMap); + } } if (m_volumePhotonMap.get() == NULL && m_volumePhotons > 0) { @@ -241,11 +247,12 @@ public: SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons()); ref volumePhotonMap = proc->getPhotonMap(); - volumePhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles()); - volumePhotonMap->build(); - - m_bre = new BeamRadianceEstimator(volumePhotonMap, m_volumeLookupSize); - m_breID = sched->registerResource(m_bre); + if (volumePhotonMap->isFull()) { + volumePhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles()); + volumePhotonMap->build(); + m_bre = new BeamRadianceEstimator(volumePhotonMap, m_volumeLookupSize); + m_breID = sched->registerResource(m_bre); + } } /* Adapt to scene extents */ @@ -311,7 +318,7 @@ public: transmittance = rRec.medium->getTransmittance(mediumRaySegment); mediumRaySegment.mint = ray.mint; if (rRec.type & RadianceQueryRecord::EVolumeRadiance && - (rRec.depth < m_maxDepth || m_maxDepth < 0)) + (rRec.depth < m_maxDepth || m_maxDepth < 0) && m_bre.get() != NULL) LiMedium = m_bre->query(mediumRaySegment, rRec.medium); } diff --git a/src/medium/heterogeneous.cpp b/src/medium/heterogeneous.cpp index de9db8d5..5ed1291e 100644 --- a/src/medium/heterogeneous.cpp +++ b/src/medium/heterogeneous.cpp @@ -86,14 +86,21 @@ static StatsCounter earlyExits("Heterogeneous volume", * } * } * + * \renderings{ + * \medrendering{40}{medium_heterogeneous_density_40} + * \medrendering{200}{medium_heterogeneous_density_200} + * \medrendering{1000}{medium_heterogeneous_density_1000} + * \caption{Renderings of an index-matched isotropic heterogeneous medium using different density multipliers (\lstref{hetvolume})} + * } + * * This plugin provides a flexible heterogeneous medium implementation, which * acquires its data from nested \code{volume} instances. These can be * constant, use a procedural function, or fetch data from disk, e.g. using a * memory-mapped density grid. See \secref{volumes} for details. * * Instead of allowing separate volumes to be provided for the scattering - * absorption parameters \code{sigmaS} and \code{sigmaA} (as is done in - * \pluginref{homogeneous}, this class instead takes the approach of + * and absorption parameters \code{sigmaS} and \code{sigmaA} (as is done in + * \pluginref{homogeneous}), this class instead takes the approach of * enforcing a spectrally uniform value of \code{sigmaT}, which must be * provided using a nested scalar-valued volume named \code{density}. * @@ -106,6 +113,48 @@ static StatsCounter earlyExits("Heterogeneous volume", * which contains local particle orientation that will be passed to * scattering models that support this, such as a the Micro-flake or * Kajiya-Kay phase functions. + * + * \vspace{4mm} + * + * \begin{xml}[label=lst:hetvolume,caption=A simple heterogeneous medium backed by a grid volume] + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * \end{xml} */ class HeterogeneousMedium : public Medium { public: diff --git a/src/medium/materials.h b/src/medium/materials.h index 75d5c8d9..97a1acbe 100644 --- a/src/medium/materials.h +++ b/src/medium/materials.h @@ -110,8 +110,6 @@ static void lookupMaterial(const Properties &props, Spectrum &sigmaS, Spectrum & sigmaA *= densityMultiplier; if (eta) *eta = matEntry->eta; - SLog(EInfo, "Setting sigmaS = %s, sigmaA = %s", - sigmaS.toString().c_str(), sigmaA.toString().c_str()); return; } ++matEntry; diff --git a/src/volume/constvolume.cpp b/src/volume/constvolume.cpp index bc54ded5..3263bdc2 100644 --- a/src/volume/constvolume.cpp +++ b/src/volume/constvolume.cpp @@ -128,6 +128,21 @@ public: return m_float; } + std::string toString() const { + std::ostringstream oss; + oss << "ConstantDataSource[value="; + if (m_type == Properties::EFloat) + oss << m_float; + else if (m_type == Properties::EPoint) + oss << m_vector.toString(); + else if (m_type == Properties::ESpectrum) + oss << m_spectrum.toString(); + else + Log(EError, "Invalid volume data type!"); + oss << "]"; + return oss.str(); + } + MTS_DECLARE_CLASS() protected: int m_type; diff --git a/src/volume/gridvolume.cpp b/src/volume/gridvolume.cpp index 18e7c55a..81d47432 100644 --- a/src/volume/gridvolume.cpp +++ b/src/volume/gridvolume.cpp @@ -263,7 +263,7 @@ public: m_channels); break; default: - Log(EError, "Encountered a volume data file of unknown type!"); + Log(EError, "Encountered a volume data file of unknown type (type=%i, channels=%i)!", type, m_channels); } m_volumeType = (EVolumeType) type; @@ -578,6 +578,16 @@ public: return 1.0f; } + std::string toString() const { + std::ostringstream oss; + oss << "GridVolume[" << endl + << " res = " << m_res.toString() << "," << endl + << " channels = " << m_channels << "," << endl + << " aabb = " << m_dataAABB.toString() << endl + << "]"; + return oss.str(); + } + MTS_DECLARE_CLASS() protected: FINLINE Vector lookupQuantizedDirection(size_t index) const {