nicer heterogeneous documentation
parent
7840a7aebb
commit
4ad2e7582c
Binary file not shown.
After Width: | Height: | Size: 101 KiB |
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
|
@ -184,11 +184,14 @@ public:
|
||||||
Log(EDebug, "Global photon map full. Shot " SIZE_T_FMT " particles, excess photons due to parallelism: "
|
Log(EDebug, "Global photon map full. Shot " SIZE_T_FMT " particles, excess photons due to parallelism: "
|
||||||
SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons());
|
SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons());
|
||||||
|
|
||||||
m_globalPhotonMap = proc->getPhotonMap();
|
ref<PhotonMap> globalPhotonMap = proc->getPhotonMap();
|
||||||
|
if (globalPhotonMap->isFull()) {
|
||||||
|
m_globalPhotonMap = globalPhotonMap;
|
||||||
m_globalPhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles());
|
m_globalPhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles());
|
||||||
m_globalPhotonMap->build();
|
m_globalPhotonMap->build();
|
||||||
m_globalPhotonMapID = sched->registerResource(m_globalPhotonMap);
|
m_globalPhotonMapID = sched->registerResource(m_globalPhotonMap);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_causticPhotonMap.get() == NULL && m_causticPhotons > 0) {
|
if (m_causticPhotonMap.get() == NULL && m_causticPhotons > 0) {
|
||||||
/* Generate the caustic photon map */
|
/* Generate the caustic photon map */
|
||||||
|
@ -212,11 +215,14 @@ public:
|
||||||
Log(EDebug, "Caustic photon map full. Shot " SIZE_T_FMT " particles, excess photons due to parallelism: "
|
Log(EDebug, "Caustic photon map full. Shot " SIZE_T_FMT " particles, excess photons due to parallelism: "
|
||||||
SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons());
|
SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons());
|
||||||
|
|
||||||
m_causticPhotonMap = proc->getPhotonMap();
|
ref<PhotonMap> causticPhotonMap = proc->getPhotonMap();
|
||||||
|
if (causticPhotonMap->isFull()) {
|
||||||
|
m_causticPhotonMap = causticPhotonMap;
|
||||||
m_causticPhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles());
|
m_causticPhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles());
|
||||||
m_causticPhotonMap->build();
|
m_causticPhotonMap->build();
|
||||||
m_causticPhotonMapID = sched->registerResource(m_causticPhotonMap);
|
m_causticPhotonMapID = sched->registerResource(m_causticPhotonMap);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_volumePhotonMap.get() == NULL && m_volumePhotons > 0) {
|
if (m_volumePhotonMap.get() == NULL && m_volumePhotons > 0) {
|
||||||
/* Generate the volume photon map */
|
/* Generate the volume photon map */
|
||||||
|
@ -241,12 +247,13 @@ public:
|
||||||
SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons());
|
SIZE_T_FMT, proc->getShotParticles(), proc->getExcessPhotons());
|
||||||
|
|
||||||
ref<PhotonMap> volumePhotonMap = proc->getPhotonMap();
|
ref<PhotonMap> volumePhotonMap = proc->getPhotonMap();
|
||||||
|
if (volumePhotonMap->isFull()) {
|
||||||
volumePhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles());
|
volumePhotonMap->setScaleFactor(1 / (Float) proc->getShotParticles());
|
||||||
volumePhotonMap->build();
|
volumePhotonMap->build();
|
||||||
|
|
||||||
m_bre = new BeamRadianceEstimator(volumePhotonMap, m_volumeLookupSize);
|
m_bre = new BeamRadianceEstimator(volumePhotonMap, m_volumeLookupSize);
|
||||||
m_breID = sched->registerResource(m_bre);
|
m_breID = sched->registerResource(m_bre);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Adapt to scene extents */
|
/* Adapt to scene extents */
|
||||||
m_globalLookupRadius = m_globalLookupRadiusRel * scene->getBSphere().radius;
|
m_globalLookupRadius = m_globalLookupRadiusRel * scene->getBSphere().radius;
|
||||||
|
@ -311,7 +318,7 @@ public:
|
||||||
transmittance = rRec.medium->getTransmittance(mediumRaySegment);
|
transmittance = rRec.medium->getTransmittance(mediumRaySegment);
|
||||||
mediumRaySegment.mint = ray.mint;
|
mediumRaySegment.mint = ray.mint;
|
||||||
if (rRec.type & RadianceQueryRecord::EVolumeRadiance &&
|
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);
|
LiMedium = m_bre->query(mediumRaySegment, rRec.medium);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
* This plugin provides a flexible heterogeneous medium implementation, which
|
||||||
* acquires its data from nested \code{volume} instances. These can be
|
* 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
|
* constant, use a procedural function, or fetch data from disk, e.g. using a
|
||||||
* memory-mapped density grid. See \secref{volumes} for details.
|
* memory-mapped density grid. See \secref{volumes} for details.
|
||||||
*
|
*
|
||||||
* Instead of allowing separate volumes to be provided for the scattering
|
* Instead of allowing separate volumes to be provided for the scattering
|
||||||
* absorption parameters \code{sigmaS} and \code{sigmaA} (as is done in
|
* and absorption parameters \code{sigmaS} and \code{sigmaA} (as is done in
|
||||||
* \pluginref{homogeneous}, this class instead takes the approach of
|
* \pluginref{homogeneous}), this class instead takes the approach of
|
||||||
* enforcing a spectrally uniform value of \code{sigmaT}, which must be
|
* enforcing a spectrally uniform value of \code{sigmaT}, which must be
|
||||||
* provided using a nested scalar-valued volume named \code{density}.
|
* 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
|
* which contains local particle orientation that will be passed to
|
||||||
* scattering models that support this, such as a the Micro-flake or
|
* scattering models that support this, such as a the Micro-flake or
|
||||||
* Kajiya-Kay phase functions.
|
* Kajiya-Kay phase functions.
|
||||||
|
*
|
||||||
|
* \vspace{4mm}
|
||||||
|
*
|
||||||
|
* \begin{xml}[label=lst:hetvolume,caption=A simple heterogeneous medium backed by a grid volume]
|
||||||
|
* <!-- Declare a heterogeneous participating medium named 'smoke' -->
|
||||||
|
* <medium type="heterogeneous" id="smoke">
|
||||||
|
* <string name="method" value="simpson"/>
|
||||||
|
*
|
||||||
|
* <!-- Acquire density values from an external data file -->
|
||||||
|
* <volume name="density" type="gridvolume">
|
||||||
|
* <string name="filename" value="frame_0150.vol"/>
|
||||||
|
* </volume>
|
||||||
|
*
|
||||||
|
* <!-- The albedo is constant and set to 0.9 -->
|
||||||
|
* <volume name="albedo" type="constvolume">
|
||||||
|
* <spectrum name="value" value="0.9"/>
|
||||||
|
* </volume>
|
||||||
|
*
|
||||||
|
* <!-- Use an isotropic phase function -->
|
||||||
|
* <phase type="isotropic"/>
|
||||||
|
*
|
||||||
|
* <!-- Scale the density values as desired -->
|
||||||
|
* <float name="densityMultiplier" value="200"/>
|
||||||
|
* </medium>
|
||||||
|
*
|
||||||
|
* <!-- Attach the index-matched medium to a shape in the scene -->
|
||||||
|
* <shape type="obj">
|
||||||
|
* <!-- Load an OBJ file, which contains a mesh version
|
||||||
|
* of the axis-aligned box of the volume data file -->
|
||||||
|
* <string name="filename" value="bounds.obj"/>
|
||||||
|
*
|
||||||
|
* <!-- Reference the medium by ID -->
|
||||||
|
* <ref name="interior" id="smoke"/>
|
||||||
|
*
|
||||||
|
* <!-- If desired, this shape could also declare
|
||||||
|
* a BSDF to create an index-mismatched
|
||||||
|
* transition, e.g.
|
||||||
|
*
|
||||||
|
* <bsdf type="dielectric"/>
|
||||||
|
* -->
|
||||||
|
* </shape>
|
||||||
|
* \end{xml}
|
||||||
*/
|
*/
|
||||||
class HeterogeneousMedium : public Medium {
|
class HeterogeneousMedium : public Medium {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -110,8 +110,6 @@ static void lookupMaterial(const Properties &props, Spectrum &sigmaS, Spectrum &
|
||||||
sigmaA *= densityMultiplier;
|
sigmaA *= densityMultiplier;
|
||||||
if (eta)
|
if (eta)
|
||||||
*eta = matEntry->eta;
|
*eta = matEntry->eta;
|
||||||
SLog(EInfo, "Setting sigmaS = %s, sigmaA = %s",
|
|
||||||
sigmaS.toString().c_str(), sigmaA.toString().c_str());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
++matEntry;
|
++matEntry;
|
||||||
|
|
|
@ -128,6 +128,21 @@ public:
|
||||||
return m_float;
|
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()
|
MTS_DECLARE_CLASS()
|
||||||
protected:
|
protected:
|
||||||
int m_type;
|
int m_type;
|
||||||
|
|
|
@ -263,7 +263,7 @@ public:
|
||||||
m_channels);
|
m_channels);
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
m_volumeType = (EVolumeType) type;
|
||||||
|
@ -578,6 +578,16 @@ public:
|
||||||
return 1.0f;
|
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()
|
MTS_DECLARE_CLASS()
|
||||||
protected:
|
protected:
|
||||||
FINLINE Vector lookupQuantizedDirection(size_t index) const {
|
FINLINE Vector lookupQuantizedDirection(size_t index) const {
|
||||||
|
|
Loading…
Reference in New Issue