further tweaks

metadata
Wenzel Jakob 2011-03-09 10:53:41 +01:00
parent 419fb7843f
commit 9e922042c3
10 changed files with 113 additions and 67 deletions

View File

@ -320,12 +320,14 @@ template<typename T> inline T endianness_swap(T value) {
}
/// Return a string representation of a list of objects
template<class T> std::string listToString(const std::vector<T> &vec) {
template<class Iterator> std::string containerToString(const Iterator &start, const Iterator &end) {
std::ostringstream oss;
oss << "{" << endl;
for (size_t i=0; i<vec.size(); ++i) {
oss << " " << indent(vec[i]->toString());
if (i != vec.size()-1)
Iterator it = start;
while (it != end) {
oss << " " << indent((*it)->toString());
++it;
if (it != end)
oss << "," << endl;
else
oss << endl;

View File

@ -299,9 +299,8 @@ public:
* Include indirect illumination in the estimate?
*/
virtual Spectrum E(const Scene *scene, const Point &p, const
Normal &n, Float time, const Medium *medium,
Sampler *sampler, int nSamples,
bool includeIndirect) const;
Normal &n, Float time, const Medium *medium, Sampler *sampler,
int nSamples, bool includeIndirect) const;
/**
* Perform the main rendering task. The work is automatically

View File

@ -33,6 +33,9 @@ public:
/// Create an invalid shadow ray sampling record
inline LuminaireSamplingRecord() : luminaire(NULL) { }
/// Create a shadow ray sampling record based on a surface intersection
inline LuminaireSamplingRecord(const Intersection &its, const Vector &direction);
/// Return a string representation
std::string toString() const;
public:

View File

@ -81,7 +81,14 @@ inline const Medium *Intersection::getTargetMedium(const Ray &ray) const {
else
return shape->getInteriorMedium();
}
inline LuminaireSamplingRecord::LuminaireSamplingRecord(const Intersection &its, const Vector &dir) {
sRec.p = its.p;
sRec.n = its.geoFrame.n;
d = dir;
luminaire = its.shape->getLuminaire();
}
inline bool RadianceQueryRecord::rayIntersect(const RayDifferential &ray) {
/* Only search for an intersection if this was explicitly requested */
if (type & EIntersection) {

View File

@ -317,7 +317,10 @@ public:
inline Spectrum LeAttenuatedBackground(const Ray &ray, const Medium *medium) const {
if (!m_backgroundLuminaire)
return Spectrum(0.0f);
return LeBackground(ray) * medium->tau(ray);
Spectrum result = LeBackground(ray);
if (medium)
result *= medium->tau(ray);
return result;
}
//! @}
@ -418,9 +421,9 @@ public:
/// Return the scene's luminaires
inline const std::vector<Luminaire *> &getLuminaires() const { return m_luminaires; }
/// Return the scene's participating media
inline std::vector<Medium *> &getMedia() { return m_media; }
inline std::set<Medium *> &getMedia() { return m_media; }
/// Return the scene's participating media
inline const std::vector<Medium *> &getMedia() const { return m_media; }
inline const std::set<Medium *> &getMedia() const { return m_media; }
/// Return referenced objects (such as textures, BSDFs)
inline std::vector<ConfigurableObject *> &getReferencedObjects() { return m_objects; }
/// Return referenced objects (such as textures, BSDFs)
@ -470,10 +473,10 @@ private:
std::vector<TriMesh *> m_meshes;
std::vector<Shape *> m_shapes;
std::vector<Luminaire *> m_luminaires;
std::vector<Medium *> m_media;
std::vector<Subsurface *> m_ssIntegrators;
std::vector<ConfigurableObject *> m_objects;
std::vector<NetworkedObject *> m_netObjects;
std::set<Medium *> m_media;
fs::path m_sourceFile;
fs::path m_destinationFile;
DiscretePDF m_luminairePDF;

View File

@ -95,7 +95,7 @@ public:
wi = Vector(-wo.x, -wo.y, wo.z);
}
Float refract(Float &intIOR, Float &extIOR,
Float refract(Float intIOR, Float extIOR,
const Vector &wi, Vector &wo, ETransportQuantity quantity) const {
Float cosTheta1 = Frame::cosTheta(wi);
bool entering = cosTheta1 > 0.0f;

View File

@ -127,7 +127,7 @@ public:
for (int i=0; i<numLuminaireSamples; ++i) {
/* Estimate the direct illumination if this is requested */
if (scene->sampleLuminaire(its, lRec, sampleArray[i])) {
if (scene->sampleLuminaire(its.p, ray.time, lRec, sampleArray[i])) {
/* Allocate a record for querying the BSDF */
const BSDFQueryRecord bRec(rRec, its, its.toLocal(-lRec.d));
@ -181,7 +181,7 @@ public:
}
} else {
/* No intersection found. Possibly, there is a background
luminaire such as an environment map? */
luminaire such as an environment map? */
if (scene->hasBackgroundLuminaire()) {
lRec.luminaire = scene->getBackgroundLuminaire();
lRec.d = -bsdfRay.d;

View File

@ -112,8 +112,9 @@ Scene::Scene(Scene *scene) : NetworkedObject(Properties()) {
for (size_t i=0; i<m_luminaires.size(); ++i)
m_luminaires[i]->incRef();
m_media = scene->m_media;
for (size_t i=0; i<m_media.size(); ++i)
m_media[i]->incRef();
for (std::set<Medium *>::iterator it = m_media.begin();
it != m_media.end(); ++it)
(*it)->incRef();
m_ssIntegrators = scene->m_ssIntegrators;
for (size_t i=0; i<m_ssIntegrators.size(); ++i)
m_ssIntegrators[i]->incRef();
@ -168,7 +169,7 @@ Scene::Scene(Stream *stream, InstanceManager *manager)
for (int i=0; i<count; ++i) {
Medium *medium = static_cast<Medium *>(manager->getInstance(stream));
medium->incRef();
m_media.push_back(medium);
m_media.insert(medium);
}
count = stream->readInt();
for (int i=0; i<count; ++i) {
@ -195,14 +196,15 @@ Scene::~Scene() {
m_shapes[i]->decRef();
for (size_t i=0; i<m_meshes.size(); i++)
m_meshes[i]->decRef();
for (size_t i=0; i<m_media.size(); i++)
m_media[i]->decRef();
for (size_t i=0; i<m_objects.size(); i++)
m_objects[i]->decRef();
for (size_t i=0; i<m_ssIntegrators.size(); i++)
m_ssIntegrators[i]->decRef();
for (size_t i=0; i<m_luminaires.size(); i++)
m_luminaires[i]->decRef();
for (std::set<Medium *>::iterator it = m_media.begin();
it != m_media.end(); ++it)
(*it)->decRef();
}
void Scene::bindUsedResources(ParallelProcess *proc) const {
@ -390,42 +392,46 @@ bool Scene::sampleAttenuatedLuminaire(const Point &p, Float time,
luminaire->sample(p, lRec, sample);
if (lRec.pdf != 0) {
Vector d = lRec.sRec.p - p;
Float distance = d.length(), traveled = 0;
d /= distance;
distance *= 1-Epsilon;
const Shape *shape;
Ray ray(p, d, time);
int iterations = 0;
while (true) {
Normal n;
Float t;
bool surface = rayIntersect(ray, t, shape, n);
if (medium)
lRec.value *= medium->tau(Ray(ray.o, d, 0, t, time));
if (!surface)
break;
ray.o = ray(t);
traveled += t;
if (shape->isOccluder() && traveled < distance)
if (m_media.size() == 0) {
if (isOccluded(p, lRec.sRec.p, time))
return false;
else if (shape->isMediumTransition())
medium = dot(n, d) > 0 ? shape->getExteriorMedium()
: shape->getInteriorMedium();
} else {
Vector d = lRec.sRec.p - p;
Float distance = d.length(), traveled = 0;
d /= distance;
distance *= 1-Epsilon;
if (++iterations > 100) { /// Just a precaution..
Log(EWarn, "sampleAttenuatedLuminaire(): round-off error issues?");
break;
const Shape *shape;
Ray ray(p, d, time);
int iterations = 0;
while (true) {
Normal n;
Float t;
bool surface = rayIntersect(ray, t, shape, n);
if (medium)
lRec.value *= medium->tau(Ray(ray.o, d, 0, t, time));
if (!surface)
break;
ray.o = ray(t);
traveled += t;
if (shape->isOccluder() && traveled < distance)
return false;
else if (shape->isMediumTransition())
medium = dot(n, d) > 0 ? shape->getExteriorMedium()
: shape->getInteriorMedium();
if (++iterations > 100) { /// Just a precaution..
Log(EWarn, "sampleAttenuatedLuminaire(): round-off error issues?");
break;
}
}
}
lRec.pdf *= lumPdf;
lRec.value /= lRec.pdf;
lRec.luminaire = luminaire;
@ -497,8 +503,10 @@ void Scene::addChild(const std::string &name, ConfigurableObject *child) {
m_objects.push_back(obj);
} else if (cClass->derivesFrom(Medium::m_theClass)) {
Medium *medium = static_cast<Medium *>(child);
medium->incRef();
m_media.push_back(medium);
if (m_media.find(medium) == m_media.end()) {
medium->incRef();
m_media.insert(medium);
}
} else if (cClass->derivesFrom(Luminaire::m_theClass)) {
Luminaire *luminaire = static_cast<Luminaire *>(child);
luminaire->incRef();
@ -531,8 +539,9 @@ void Scene::addChild(const std::string &name, ConfigurableObject *child) {
obj->setParent(this);
addChild("object", obj);
}
for (size_t i=0; i<scene->getMedia().size(); ++i) {
Medium *medium = scene->getMedia()[i];
for (std::set<Medium *>::iterator it = scene->getMedia().begin();
it != scene->getMedia().end(); ++it) {
Medium *medium = *it;
medium->setParent(this);
addChild("medium", medium);
}
@ -575,6 +584,20 @@ void Scene::addShape(Shape *shape) {
shape->getSubsurface()->incRef();
}
}
Medium *iMedium = shape->getInteriorMedium(),
*eMedium = shape->getExteriorMedium();
if (eMedium != NULL && m_media.find(eMedium) == m_media.end()) {
m_media.insert(eMedium);
eMedium->incRef();
}
if (iMedium != NULL && m_media.find(iMedium) == m_media.end()) {
m_media.insert(iMedium);
iMedium->incRef();
}
if (shape->getClass()->derivesFrom(TriMesh::m_theClass)) {
if (std::find(m_meshes.begin(), m_meshes.end(), shape)
== m_meshes.end()) {
@ -582,6 +605,7 @@ void Scene::addShape(Shape *shape) {
shape->incRef();
}
}
shape->incRef();
m_kdtree->addShape(shape);
m_shapes.push_back(shape);
@ -618,8 +642,9 @@ void Scene::serialize(Stream *stream, InstanceManager *manager) const {
for (size_t i=0; i<m_luminaires.size(); ++i)
manager->serialize(stream, m_luminaires[i]);
stream->writeUInt((uint32_t) m_media.size());
for (size_t i=0; i<m_media.size(); ++i)
manager->serialize(stream, m_media[i]);
for (std::set<Medium *>::iterator it = m_media.begin();
it != m_media.end(); ++it)
manager->serialize(stream, *it);
stream->writeUInt((uint32_t) m_ssIntegrators.size());
for (size_t i=0; i<m_ssIntegrators.size(); ++i)
manager->serialize(stream, m_ssIntegrators[i]);
@ -643,12 +668,12 @@ std::string Scene::toString() const {
<< " integrator = " << indent(m_integrator.toString()) << "," << endl
<< " kdtree = " << indent(m_kdtree.toString()) << "," << endl
<< " backgroundLuminaire = " << indent(m_backgroundLuminaire.toString()) << "," << endl
<< " meshes = " << indent(listToString(m_meshes)) << "," << endl
<< " shapes = " << indent(listToString(m_shapes)) << "," << endl
<< " luminaires = " << indent(listToString(m_luminaires)) << "," << endl
<< " media = " << indent(listToString(m_media)) << "," << endl
<< " ssIntegrators = " << indent(listToString(m_ssIntegrators)) << "," << endl
<< " objects = " << indent(listToString(m_objects)) << endl;
<< " meshes = " << indent(containerToString(m_meshes.begin(), m_meshes.end())) << "," << endl
<< " shapes = " << indent(containerToString(m_shapes.begin(), m_shapes.end())) << "," << endl
<< " luminaires = " << indent(containerToString(m_luminaires.begin(), m_luminaires.end())) << "," << endl
<< " media = " << indent(containerToString(m_media.begin(), m_media.end())) << "," << endl
<< " ssIntegrators = " << indent(containerToString(m_ssIntegrators.begin(), m_ssIntegrators.end())) << "," << endl
<< " objects = " << indent(containerToString(m_objects.begin(), m_objects.end())) << endl;
oss << "]";
return oss.str();
}

View File

@ -458,6 +458,12 @@ public:
child->setParent(m_meshes[i]);
m_meshes[i]->addChild(name, child);
}
} else if (cClass->derivesFrom(Medium::m_theClass)) {
Assert(m_subsurface == NULL);
for (size_t i=0; i<m_meshes.size(); ++i) {
child->setParent(m_meshes[i]);
m_meshes[i]->addChild(name, child);
}
} else {
Shape::addChild(name, child);
}

View File

@ -27,7 +27,8 @@ MTS_NAMESPACE_BEGIN
class IrradianceSamplingWorker : public WorkProcessor {
public:
IrradianceSamplingWorker(size_t sampleCount, int ssIndex, int irrSamples, bool irrIndirect)
: m_sampleCount(sampleCount), m_ssIndex(ssIndex), m_irrSamples(irrSamples), m_irrIndirect(irrIndirect) {
: m_sampleCount(sampleCount), m_ssIndex(ssIndex),
m_irrSamples(irrSamples), m_irrIndirect(irrIndirect) {
}
IrradianceSamplingWorker(Stream *stream, InstanceManager *manager) {
@ -93,8 +94,8 @@ public:
result->put(IrradianceSample(
sRec.p,
integrator->E(m_scene.get(), sRec.p, sRec.n, time,
m_independentSampler, m_irrSamples, m_irrIndirect),
1/pdf
camera->getMedium(), m_independentSampler,
m_irrSamples, m_irrIndirect), 1/pdf
));
}
}