diff --git a/src/bsdfs/irawan.cpp b/src/bsdfs/irawan.cpp index 753cd7d9..de3a8aea 100644 --- a/src/bsdfs/irawan.cpp +++ b/src/bsdfs/irawan.cpp @@ -19,7 +19,6 @@ along with this program. If not, see . */ - #include #include #include @@ -37,9 +36,9 @@ MTS_NAMESPACE_BEGIN * This plugin implements the Irawan & Marschner woven cloth BRDF model * It is a port of a previous Java implementation by Piti Irawan. * - * To use the model, you must provide a special weave pattern file, as well - * as diffuse and specular texture maps. For an example of what these look - * like, please see the included example scenes. + * To use the model, you must provide a special weave pattern file -- + * for an example of what these look like, please see the included + * example scenes. * * For reference, the model is described in detail in the PhD * thesis of Piti Irawan ("The Appearance of Woven Cloth", @@ -74,26 +73,25 @@ public: SAssert(m_pattern.pattern.size() == m_pattern.tileWidth * m_pattern.tileHeight); for (size_t i=0; i 0 && + m_pattern.pattern[i] <= m_pattern.yarns.size()); /* U and V tile count */ m_repeatU = props.getFloat("repeatU"); m_repeatV = props.getFloat("repeatV"); - /* Diffuse and specular multiplier */ - m_kd = props.getFloat("kd"); - m_ks = props.getFloat("ks"); + /* Diffuse and specular multipliers */ + m_kdMultiplier = props.getFloat("kdMultiplier"); + m_ksMultiplier = props.getFloat("ksMultiplier"); } IrawanClothBRDF(Stream *stream, InstanceManager *manager) : BSDF(stream, manager) { - m_diffuseReflectance = static_cast(manager->getInstance(stream)); - m_specularReflectance = static_cast(manager->getInstance(stream)); m_pattern = WeavePattern(stream); m_repeatU = stream->readFloat(); m_repeatV = stream->readFloat(); - m_kd = stream->readFloat(); - m_ks = stream->readFloat(); + m_kdMultiplier = stream->readFloat(); + m_ksMultiplier = stream->readFloat(); m_componentCount = 1; m_type = new unsigned int[m_componentCount]; m_combinedType = m_type[0] = EGlossyReflection | EAnisotropicMaterial; @@ -120,10 +118,6 @@ public: int yarnID = m_pattern.pattern[lookup.x + lookup.y * m_pattern.tileWidth] - 1; const Yarn &yarn = m_pattern.yarns.at(yarnID); - - Spectrum diffuse = m_diffuseReflectance->getValue(uv); - Spectrum specular = m_specularReflectance->getValue(uv); - // store center of the yarn segment Point2 center (((int) xy.x / m_pattern.tileWidth) * m_pattern.tileWidth @@ -195,7 +189,7 @@ public: // Compute specular contribution. Spectrum result(0.0f); - if (m_ks > 0.0f) { + if (m_ksMultiplier > 0.0f) { Float integrand; if (psi != 0.0f) integrand = evalStapleIntegrand(u, v, om_i, om_r, m_pattern.alpha, @@ -218,18 +212,27 @@ public: intensityVariation = std::min(-std::log(xi), (Float) 10.0f); } - result = specular * (intensityVariation * m_ks * integrand); + result = yarn.ks * (intensityVariation * m_ksMultiplier * integrand); if (type == Yarn::EWarp) result *= (m_pattern.warpArea + m_pattern.weftArea) / m_pattern.warpArea; else result *= (m_pattern.warpArea + m_pattern.weftArea) / m_pattern.weftArea; } - return result + diffuse * m_kd; + return result + yarn.kd * m_kdMultiplier; } Spectrum getDiffuseReflectance(const Intersection &its) const { - return m_diffuseReflectance->getValue(its); + Point2 uv = Point2(its.uv.x * m_repeatU, + (1 - its.uv.y) * m_repeatV); + Point2 xy(uv.x * m_pattern.tileWidth, uv.y * m_pattern.tileHeight); + Point2i lookup( + modulo((int) xy.x, m_pattern.tileWidth), + modulo((int) xy.y, m_pattern.tileHeight)); + int yarnID = m_pattern.pattern[lookup.x + lookup.y * m_pattern.tileWidth] - 1; + const Yarn &yarn = m_pattern.yarns.at(yarnID); + + return yarn.kd * m_kdMultiplier; } Float pdf(const BSDFQueryRecord &bRec) const { @@ -259,35 +262,14 @@ public: return f(bRec); } - void addChild(const std::string &name, ConfigurableObject *child) { - if (child->getClass()->derivesFrom(MTS_CLASS(Texture2D)) - && name == "diffuseReflectance") { - m_diffuseReflectance = static_cast(child); - } else if (child->getClass()->derivesFrom(MTS_CLASS(Texture2D)) - && name == "specularReflectance") { - m_specularReflectance = static_cast(child); - } else { - BSDF::addChild(name, child); - } - } - - void configure() { - if (m_diffuseReflectance == NULL || - m_specularReflectance == NULL) - Log(EError, "Missing texture component (diffuse " - "+ specular map are required)"); - } - void serialize(Stream *stream, InstanceManager *manager) const { BSDF::serialize(stream, manager); - manager->serialize(stream, m_diffuseReflectance.get()); - manager->serialize(stream, m_specularReflectance.get()); m_pattern.serialize(stream); stream->writeFloat(m_repeatU); stream->writeFloat(m_repeatV); - stream->writeFloat(m_kd); - stream->writeFloat(m_ks); + stream->writeFloat(m_kdMultiplier); + stream->writeFloat(m_ksMultiplier); } /** parameters: @@ -537,20 +519,21 @@ public: std::string toString() const { std::ostringstream oss; oss << "IrawanClothBRDF[" << endl - << " diffuseReflectance = " << indent(m_diffuseReflectance.toString()) << "," << endl - << " specularReflectance = " << indent(m_specularReflectance.toString()) << endl - << " weavePattern = " << indent(m_pattern.toString()) << endl + << " weavePattern = " << indent(m_pattern.toString()) << "," << endl + << " repeatU = " << m_repeatU << "," << endl + << " repeatV = " << m_repeatV << "," << endl + << " kdMultiplier = " << m_kdMultiplier << "," << endl + << " ksMultiplier = " << m_ksMultiplier << endl << "]"; return oss.str(); } MTS_DECLARE_CLASS() private: - ref m_diffuseReflectance; - ref m_specularReflectance; WeavePattern m_pattern; Float m_repeatU, m_repeatV; - Float m_kd, m_ks; + Float m_kdMultiplier; + Float m_ksMultiplier; }; MTS_IMPLEMENT_CLASS_S(IrawanClothBRDF, false, BSDF) diff --git a/src/bsdfs/irawan.h b/src/bsdfs/irawan.h index f0f0a782..7e40bc9e 100644 --- a/src/bsdfs/irawan.h +++ b/src/bsdfs/irawan.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -276,14 +275,6 @@ template struct SkipGrammar : qi::grammar { qi::rule start; }; -inline Spectrum lookupSpectrum(const std::map &map, const std::vector &_name) { - std::string name = std::string(&_name[0]); - std::map::const_iterator it = map.find(name); - if (it == map.end()) - SLog(EError, "Unable to find key \"%s\"", name.c_str()); - return it->second; -} - template struct YarnGrammar : qi::grammar > { YarnGrammar(const Properties &props) : YarnGrammar::base_type(start), props(props) { @@ -297,14 +288,15 @@ template struct YarnGrammar : qi::grammar id = qi::lexeme[ lit('$') >> +char_("a-zA-Z0-9") ]; + identifier = qi::lexeme[ lit('$') >> (qi::alpha | char_('_')) + >> *(qi::alnum | char_('_')) ]; spec = ((lit("{") >> float_ >> lit(",") >> float_ >> lit(",") >> float_ >> lit("}")) [ ph::bind(&Spectrum::fromLinearRGB, _val, _1, _2, _3) ]) - | (id [ _val = bind(&Properties::getSpectrum, ph::ref(props), _1)]); + | (identifier [ _val = bind(&Properties::getSpectrum, ph::ref(props), _1)]); flt = (float_ [ _val = _1 ]) - | (id [ _val = bind(&Properties::getFloat, ph::ref(props), _1)]); + | (identifier [ _val = bind(&Properties::getFloat, ph::ref(props), _1)]); start = lit("yarn") >> lit("{") @@ -327,6 +319,7 @@ template struct YarnGrammar : qi::grammar > start; qi::rule > spec; qi::rule > flt; + qi::rule identifier; const Properties &props; }; @@ -346,12 +339,13 @@ template struct WeavePatternGrammar : qi::grammar> uint_ [ push_back(_val, _1) ] % ',' >> lit("}"); - name = ("\"" >> *(char_ - "\"") >> "\""); + name = qi::lexeme [ lit("\"") >> *(char_ - "\"") >> lit("\"") ]; - qi::rule id = qi::lexeme[ lit('$') >> +char_("a-zA-Z0-9") ]; + identifier = qi::lexeme[ lit('$') >> (qi::alpha | char_('_')) + >> *(qi::alnum | char_('_')) ]; flt = (float_ [ _val = _1 ]) - | (id [ _val = bind(&Properties::getFloat, ph::ref(props), _1)]); + | (identifier [ _val = bind(&Properties::getFloat, ph::ref(props), _1)]); start = lit("weave") >> lit("{") >> ( lit("name") >> lit("=") >> name [ bind(&WeavePattern::name, _val) = _1 ] @@ -372,13 +366,14 @@ template struct WeavePatternGrammar : qi::grammar> lit("}"); + >> lit("}") >> qi::eoi; } qi::rule > start; qi::rule(), SkipGrammar > pattern; qi::rule > name; qi::rule > flt; + qi::rule identifier; YarnGrammar yarn; const Properties &props; };