diff --git a/data/schema/scene.xsd b/data/schema/scene.xsd
index 85f7eb9e..a088e76c 100644
--- a/data/schema/scene.xsd
+++ b/data/schema/scene.xsd
@@ -7,7 +7,7 @@
-
+
diff --git a/src/bsdfs/SConscript b/src/bsdfs/SConscript
index 3b5b724c..2cafe5ce 100644
--- a/src/bsdfs/SConscript
+++ b/src/bsdfs/SConscript
@@ -12,6 +12,7 @@ plugins += env.SharedLibrary('roughplastic', ['roughplastic.cpp'])
# Materials that act as modifiers
plugins += env.SharedLibrary('twosided', ['twosided.cpp'])
+plugins += env.SharedLibrary('force_twosided', ['force_twosided.cpp'])
plugins += env.SharedLibrary('mask', ['mask.cpp'])
plugins += env.SharedLibrary('mixturebsdf', ['mixturebsdf.cpp'])
plugins += env.SharedLibrary('blendbsdf', ['blendbsdf.cpp'])
diff --git a/src/integrators/bdpt/bdpt.h b/src/integrators/bdpt/bdpt.h
index 384cc146..51a74328 100644
--- a/src/integrators/bdpt/bdpt.h
+++ b/src/integrators/bdpt/bdpt.h
@@ -27,7 +27,7 @@
* rendering into the weighted contributions of the individual sampling
* strategies.
*/
-//#define BDPT_DEBUG 1
+#define BDPT_DEBUG 1
MTS_NAMESPACE_BEGIN
diff --git a/src/integrators/bdpt/bdpt_wr.cpp b/src/integrators/bdpt/bdpt_wr.cpp
index 54fcdd5a..b4af7e79 100644
--- a/src/integrators/bdpt/bdpt_wr.cpp
+++ b/src/integrators/bdpt/bdpt_wr.cpp
@@ -95,12 +95,12 @@ void BDPTWorkResult::dump(const BDPTConfiguration &conf,
for (int t=0; t<=k+1; ++t) {
size_t s = k+1-t;
Bitmap *bitmap = const_cast(m_debugBlocks[strategyIndex(s, t)]->getBitmap());
- ref ldrBitmap = bitmap->convert(Bitmap::ERGB, Bitmap::EUInt8, -1, weight);
+ ref ldrBitmap = bitmap->convert(Bitmap::ERGB, Bitmap::EFloat32, -1, weight);
fs::path filename =
- prefix / fs::path(formatString("%s_k%02i_s%02i_t%02i.png", stem.filename().string().c_str(), k, s, t));
+ prefix / fs::path(formatString("%s_k%02i_s%02i_t%02i.exr", stem.filename().string().c_str(), k, s, t));
ref targetFile = new FileStream(filename,
FileStream::ETruncReadWrite);
- ldrBitmap->write(Bitmap::EPNG, targetFile, 1);
+ ldrBitmap->write(Bitmap::EOpenEXR, targetFile, 1);
}
}
}
diff --git a/src/integrators/misc/motion.cpp b/src/integrators/misc/motion.cpp
index b10e215a..92ba46a5 100644
--- a/src/integrators/misc/motion.cpp
+++ b/src/integrators/misc/motion.cpp
@@ -32,9 +32,9 @@ static StatsCounter statsConverged(
/*!\plugin{motion}{Motion and specular motion vector integrator}
* \parameters{
* \parameter{time}{\Float}{
- * Denotes the time stamp of the target frame of the motion vectors.
+ * Denotes the time stamp of the target frame of the motion vectors.
* The current frame is specified via the sensor's \code{shutterOpen}
- * and \code{shutterClose} parameters, which should both be set to
+ * and \code{shutterClose} parameters, which should both be set to
* the same value. \default{0}
* }
* \parameter{time}{\String}{
@@ -96,7 +96,7 @@ static StatsCounter statsConverged(
*
*
*
- *
+ *
*
*
*
@@ -109,16 +109,16 @@ static StatsCounter statsConverged(
*
*
*
- *
+ *
*
*
*
- *
+ *
*
*
*
*
- *
+ *
*
*
*
diff --git a/src/integrators/path/path.cpp b/src/integrators/path/path.cpp
index d9df52da..7bcc1130 100644
--- a/src/integrators/path/path.cpp
+++ b/src/integrators/path/path.cpp
@@ -136,9 +136,12 @@ public:
if (!its.isValid()) {
/* If no intersection could be found, potentially return
radiance from a environment luminaire if it exists */
- if ((rRec.type & RadianceQueryRecord::EEmittedRadiance)
- && (!m_hideEmitters || scattered))
- Li += throughput * scene->evalEnvironment(ray);
+ if (rRec.type & RadianceQueryRecord::EEmittedRadiance) {
+ Spectrum Le = scene->evalEnvironment(ray);
+ if (m_hideEmitters && !scattered)
+ Le = Spectrum(1.f);
+ Li += throughput * Le;
+ }
break;
}
@@ -170,10 +173,12 @@ public:
/* Estimate the direct illumination if this is requested */
DirectSamplingRecord dRec(its);
+ bool backgroundPlate = rRec.depth == 1 && its.shape->getName().find("background") != std::string::npos;
if (rRec.type & RadianceQueryRecord::EDirectSurfaceRadiance &&
(bsdf->getType() & BSDF::ESmooth)) {
Spectrum value = scene->sampleEmitterDirect(dRec, rRec.nextSample2D());
+
if (!value.isZero()) {
const Emitter *emitter = static_cast(dRec.object);
@@ -194,10 +199,22 @@ public:
/* Weight using the power heuristic */
Float weight = miWeight(dRec.pdf, bsdfPdf);
- Li += throughput * value * bsdfVal * weight;
+ if (backgroundPlate) {
+ Li += Spectrum(1.0f);
+ rRec.alpha = 0.0f;
+ } else {
+ Li += throughput * value * bsdfVal * weight;
+ }
}
}
}
+ if (backgroundPlate) {
+ if (dot(dRec.refN, dRec.d) < 0) {
+ Li += Spectrum(1.0f);
+ rRec.alpha = 0.0f;
+ }
+ break;
+ }
/* ==================================================================== */
/* BSDF sampling */
diff --git a/src/integrators/pssmlt/pssmlt.cpp b/src/integrators/pssmlt/pssmlt.cpp
index 03f0fc33..03f07ad2 100644
--- a/src/integrators/pssmlt/pssmlt.cpp
+++ b/src/integrators/pssmlt/pssmlt.cpp
@@ -358,6 +358,8 @@ public:
m_config.luminance = pathSampler->generateSeeds(luminanceSamples,
m_config.workUnits, false, m_config.importanceMap, pathSeeds);
+ cout << "Luminance = " << m_config.luminance << endl;
+
if (!nested)
m_config.dump();
diff --git a/src/samplers/ldsampler.cpp b/src/samplers/ldsampler.cpp
index 6ee12385..0bc48dce 100644
--- a/src/samplers/ldsampler.cpp
+++ b/src/samplers/ldsampler.cpp
@@ -36,6 +36,10 @@ MTS_NAMESPACE_BEGIN
* increase both storage and computational costs.
* \default{4}
* }
+ * \parameter{pixelCenters}{\Integer}{
+ * Place samples at pixel centers. This is useful for use with the
+ * \pluginref{field} integrator.
+ * }
* }
* \vspace{-2mm}
* \renderings{
@@ -79,6 +83,11 @@ public:
/* Dimension, up to which which low discrepancy samples are guaranteed to be available. */
m_maxDimension = props.getInteger("dimension", 4);
+ if (m_maxDimension < 1)
+ Log(EError, "Dimension parameter must be > 0!");
+
+ /* Place samples at pixel centers? */
+ m_pixelCenters = props.getBoolean("pixelCenters", false);
if (!math::isPowerOfTwo(m_sampleCount)) {
m_sampleCount = math::roundToPowerOfTwo(m_sampleCount);
@@ -101,6 +110,7 @@ public:
: Sampler(stream, manager) {
m_random = static_cast(manager->getInstance(stream));
m_maxDimension = stream->readSize();
+ m_pixelCenters = stream->readBool();
m_samples1D = new Float*[m_maxDimension];
m_samples2D = new Point2*[m_maxDimension];
@@ -123,6 +133,7 @@ public:
Sampler::serialize(stream, manager);
manager->serialize(stream, m_random.get());
stream->writeSize(m_maxDimension);
+ stream->writeBool(m_pixelCenters);
}
ref clone() {
@@ -197,6 +208,9 @@ public:
m_sampleIndex = 0;
m_dimension1D = m_dimension2D = 0;
m_dimension1DArray = m_dimension2DArray = 0;
+
+ if (m_pixelCenters)
+ m_samples2D[0][0] = Point2(0.5f);
}
void advance() {
@@ -231,7 +245,8 @@ public:
std::ostringstream oss;
oss << "LowDiscrepancySampler[" << endl
<< " sampleCount = " << m_sampleCount << "," << endl
- << " dimension = " << m_maxDimension << endl
+ << " dimension = " << m_maxDimension << "," << endl
+ << " pixelCenters = " << m_pixelCenters << endl
<< "]";
return oss.str();
}
@@ -244,6 +259,7 @@ private:
size_t m_dimension2D;
Float **m_samples1D;
Point2 **m_samples2D;
+ bool m_pixelCenters;
};
MTS_IMPLEMENT_CLASS_S(LowDiscrepancySampler, false, Sampler)
diff --git a/src/shapes/obj.cpp b/src/shapes/obj.cpp
index 65b2a550..3dae112c 100644
--- a/src/shapes/obj.cpp
+++ b/src/shapes/obj.cpp
@@ -319,7 +319,13 @@ public:
t.uv[1] = t.uv[2];
t.n[1] = t.n[2];
parse(t, 2, tmp);
- triangles.push_back(t);
+ OBJTriangle tp = tp;
+ for (int i=0; i<3; ++i) {
+ tp.p[i] = t.p[(i+1)%3];
+ tp.uv[i] = t.uv[(i+1)%3];
+ tp.n[i] = t.n[(i+1)%3];
+ }
+ triangles.push_back(tp);
}
} else {
/* Ignore */
diff --git a/src/shapes/ply.cpp b/src/shapes/ply.cpp
index 1c2f38fd..c96045f7 100644
--- a/src/shapes/ply.cpp
+++ b/src/shapes/ply.cpp
@@ -304,7 +304,7 @@ public:
m_triangles[m_triangleCount++] = t;
if (m_indexCtr == 4) {
- t.idx[0] = m_face[3]; t.idx[1] = m_face[0]; t.idx[2] = m_face[2];
+ t.idx[0] = m_face[2]; t.idx[1] = m_face[3]; t.idx[2] = m_face[0];
m_triangles[m_triangleCount++] = t;
}
diff --git a/src/shapes/rectangle.cpp b/src/shapes/rectangle.cpp
index 5a886368..dcda82d0 100644
--- a/src/shapes/rectangle.cpp
+++ b/src/shapes/rectangle.cpp
@@ -105,8 +105,8 @@ public:
m_frame = Frame(normalize(m_dpdu), normalize(m_dpdv), normal);
m_invSurfaceArea = 1.0f / getSurfaceArea();
- if (std::abs(dot(normalize(m_dpdu), normalize(m_dpdv))) > Epsilon)
- Log(EError, "Error: 'toWorld' transformation contains shear!");
+ if (std::abs(dot(normalize(m_dpdu), normalize(m_dpdv))) > 1e-3f)
+ Log(EWarn, "Error: 'toWorld' transformation contains shear!");
}
AABB getAABB() const {
diff --git a/src/textures/SConscript b/src/textures/SConscript
index 38b5284c..839fbba9 100644
--- a/src/textures/SConscript
+++ b/src/textures/SConscript
@@ -7,5 +7,7 @@ plugins += env.SharedLibrary('checkerboard', ['checkerboard.cpp'])
plugins += env.SharedLibrary('vertexcolors', ['vertexcolors.cpp'])
plugins += env.SharedLibrary('wireframe', ['wireframe.cpp'])
plugins += env.SharedLibrary('curvature', ['curvature.cpp'])
+plugins += env.SharedLibrary('posyfield', ['posyfield.cpp'])
+plugins += env.SharedLibrary('posysing', ['posysing.cpp'])
Export('plugins')
diff --git a/src/textures/vertexcolors.cpp b/src/textures/vertexcolors.cpp
index b0a8a1be..9ce3239e 100644
--- a/src/textures/vertexcolors.cpp
+++ b/src/textures/vertexcolors.cpp
@@ -111,9 +111,6 @@ public:
}
MTS_DECLARE_CLASS()
-private:
- Spectrum m_brightReflectance;
- Spectrum m_darkReflectance;
};
Shader *VertexColors::createShader(Renderer *renderer) const {
diff --git a/src/textures/wireframe.cpp b/src/textures/wireframe.cpp
index d59b1eeb..d11a0c16 100644
--- a/src/textures/wireframe.cpp
+++ b/src/textures/wireframe.cpp
@@ -60,6 +60,7 @@ public:
m_edgeColor = props.getSpectrum("edgeColor", Spectrum(0.1f));
m_interiorColor = props.getSpectrum("interiorColor", Spectrum(.5f));
m_stepWidth = std::max((Float) 0.0f, std::min(m_stepWidth, (Float) 1.0f));
+ m_quads = props.getBoolean("quads", false);
m_mutex = new Mutex();
}
@@ -69,6 +70,7 @@ public:
m_edgeColor = Spectrum(stream);
m_interiorColor = Spectrum(stream);
m_lineWidth = stream->readFloat();
+ m_quads = stream->readBool();
}
void serialize(Stream *stream, InstanceManager *manager) const {
@@ -76,6 +78,7 @@ public:
m_edgeColor.serialize(stream);
m_interiorColor.serialize(stream);
stream->writeFloat(m_lineWidth);
+ stream->writeBool(m_quads);
}
Spectrum eval(const Intersection &its, bool /* unused */) const {
@@ -105,10 +108,20 @@ public:
}
}
- const Triangle &tri = triMesh->getTriangles()[its.primIndex];
+ bool irregular = false;
+ if (m_quads) {
+ uint32_t base = its.primIndex & ~1u;
+ const Triangle &tri1 = triMesh->getTriangles()[base+1];
+ const Point *verts = triMesh->getVertexPositions();
+ if (verts[tri1.idx[0]] == verts[tri1.idx[1]])
+ irregular = true;
+ }
+ const Triangle &tri = triMesh->getTriangles()[its.primIndex];
Float minDist = std::numeric_limits::infinity();
for (int i=0; i<3; ++i) {
+ if ((m_quads && i == 2) || (irregular && (i == 1 || (its.primIndex & 1))))
+ continue;
const Point& cur = positions[tri.idx[i]];
const Point& next = positions[tri.idx[(i+1)%3]];
@@ -162,8 +175,9 @@ public:
oss << "WireFrame[" << endl
<< " edgeColor = " << m_edgeColor.toString() << "," << endl
<< " interiorColor = " << m_interiorColor.toString() << "," << endl
- << " lineWidth = " << m_lineWidth << endl
- << " stepWidth = " << m_stepWidth << endl
+ << " lineWidth = " << m_lineWidth << "," << endl
+ << " stepWidth = " << m_stepWidth << "," << endl
+ << " quads = " << m_quads << endl
<< "]";
return oss.str();
}
@@ -177,6 +191,7 @@ protected:
Float m_stepWidth;
Spectrum m_edgeColor;
Spectrum m_interiorColor;
+ bool m_quads;
};
// ================ Hardware shader implementation ================