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 ================