Phong now takes a separate color and reflectance argument

This change will soon be implemented with the remaining materials
metadata
Wenzel Jakob 2010-08-15 15:24:30 +02:00
parent c26b116f11
commit ab2e6b4ca7
13 changed files with 185 additions and 71 deletions

View File

@ -462,6 +462,7 @@ plugins = []
plugins += env.SharedLibrary('plugins/lambertian', ['src/bsdfs/lambertian.cpp']) plugins += env.SharedLibrary('plugins/lambertian', ['src/bsdfs/lambertian.cpp'])
plugins += env.SharedLibrary('plugins/dielectric', ['src/bsdfs/dielectric.cpp']) plugins += env.SharedLibrary('plugins/dielectric', ['src/bsdfs/dielectric.cpp'])
plugins += env.SharedLibrary('plugins/mirror', ['src/bsdfs/mirror.cpp']) plugins += env.SharedLibrary('plugins/mirror', ['src/bsdfs/mirror.cpp'])
plugins += env.SharedLibrary('plugins/transparent', ['src/bsdfs/transparent.cpp'])
plugins += env.SharedLibrary('plugins/ward', ['src/bsdfs/ward.cpp']) plugins += env.SharedLibrary('plugins/ward', ['src/bsdfs/ward.cpp'])
plugins += env.SharedLibrary('plugins/phong', ['src/bsdfs/phong.cpp']) plugins += env.SharedLibrary('plugins/phong', ['src/bsdfs/phong.cpp'])
plugins += env.SharedLibrary('plugins/microfacet', ['src/bsdfs/microfacet.cpp']) plugins += env.SharedLibrary('plugins/microfacet', ['src/bsdfs/microfacet.cpp'])

View File

@ -23,16 +23,21 @@ public:
}; };
/// Construct an empty property container /// Construct an empty property container
Properties() { } Properties() : m_id("unnamed") { }
/// Construct an empty property container and set the plugin name /// Construct an empty property container and set the plugin name
Properties(const std::string &pluginName) : m_pluginName(pluginName) { } Properties(const std::string &pluginName) : m_pluginName(pluginName), m_id("unnamed") { }
/// Set the associated plugin name /// Set the associated plugin name
inline void setPluginName(const std::string &name) { m_pluginName = name; } inline void setPluginName(const std::string &name) { m_pluginName = name; }
/// Get the associated plugin name /// Get the associated plugin name
inline const std::string &getPluginName() const { return m_pluginName; } inline const std::string &getPluginName() const { return m_pluginName; }
/// Returns the associated ID (or the string "unnamed")
inline const std::string &getID() const { return m_id; }
/// Set the associated ID
inline void setID(const std::string &id) { m_id = id; }
/// Set a boolean value /// Set a boolean value
void setBoolean(const std::string &name, bool value, bool warnDuplicates = true); void setBoolean(const std::string &name, bool value, bool warnDuplicates = true);
/// Get an boolean value /// Get an boolean value
@ -129,7 +134,7 @@ private:
}; };
std::map<std::string, Element> m_elements; std::map<std::string, Element> m_elements;
std::string m_pluginName; std::string m_pluginName, m_id;
}; };
MTS_NAMESPACE_END MTS_NAMESPACE_END

View File

@ -49,6 +49,9 @@ public:
/// Return a pointer to internal image representation at full resolution /// Return a pointer to internal image representation at full resolution
inline const Spectrum *getImageData() const { return m_pyramid[0]; } inline const Spectrum *getImageData() const { return m_pyramid[0]; }
/// Get the component-wise maximum at the zero level
Spectrum getMaximum() const;
/// Return a bitmap representation of the full-resolution image /// Return a bitmap representation of the full-resolution image
Bitmap *getBitmap() const; Bitmap *getBitmap() const;

View File

@ -10,6 +10,7 @@ class MTS_EXPORT_RENDER Texture : public ConfigurableObject, public HWResource {
public: public:
virtual Spectrum getValue(const Intersection &its) const = 0; virtual Spectrum getValue(const Intersection &its) const = 0;
virtual Spectrum getAverage() const = 0; virtual Spectrum getAverage() const = 0;
virtual Spectrum getMaximum() const = 0; /* Component-wise maximum */
virtual bool usesRayDifferentials() const = 0; virtual bool usesRayDifferentials() const = 0;
virtual void serialize(Stream *stream, InstanceManager *manager) const; virtual void serialize(Stream *stream, InstanceManager *manager) const;
@ -37,6 +38,10 @@ public:
return m_value; return m_value;
} }
inline Spectrum getMaximum() const {
return m_value;
}
inline std::string toString() const { inline std::string toString() const {
std::ostringstream oss; std::ostringstream oss;
oss << "ConstantTexture[value=" << m_value.toString() << "]"; oss << "ConstantTexture[value=" << m_value.toString() << "]";

View File

@ -11,8 +11,7 @@ MTS_NAMESPACE_BEGIN
class Composite : public BSDF { class Composite : public BSDF {
public: public:
Composite(const Properties &props) Composite(const Properties &props)
: BSDF(props), m_bsdfWeight(NULL) { : BSDF(props), m_bsdfCount(0), m_bsdfWeight(NULL) {
/* Parse the weight parameter */ /* Parse the weight parameter */
std::vector<std::string> weights = std::vector<std::string> weights =
tokenize(props.getString("weights", ""), " ,;"); tokenize(props.getString("weights", ""), " ,;");
@ -37,7 +36,7 @@ public:
} }
Composite(Stream *stream, InstanceManager *manager) Composite(Stream *stream, InstanceManager *manager)
: BSDF(stream, manager), m_bsdfWeight(NULL) { : BSDF(stream, manager), m_bsdfCount(0), m_bsdfWeight(NULL) {
m_bsdfCount = stream->readInt(); m_bsdfCount = stream->readInt();
m_bsdfWeight = new Float[m_bsdfCount]; m_bsdfWeight = new Float[m_bsdfCount];
m_bsdfOffset = new int[m_bsdfCount]; m_bsdfOffset = new int[m_bsdfCount];
@ -51,7 +50,7 @@ public:
} }
virtual ~Composite() { virtual ~Composite() {
for (int i=0; i<m_bsdfCount; ++i) for (size_t i=0; i<m_bsdfs.size(); ++i)
m_bsdfs[i]->decRef(); m_bsdfs[i]->decRef();
if (m_type) if (m_type)
delete[] m_type; delete[] m_type;
@ -109,7 +108,7 @@ public:
return result; return result;
} }
inline Spectrum f(const BSDFQueryRecord &bRec) const { Spectrum f(const BSDFQueryRecord &bRec) const {
Spectrum result(0.0f); Spectrum result(0.0f);
if (bRec.component == -1) { if (bRec.component == -1) {
@ -131,6 +130,28 @@ public:
return result; return result;
} }
Spectrum fDelta(const BSDFQueryRecord &bRec) const {
Spectrum result(0.0f);
if (bRec.component == -1) {
for (int i=0; i<m_bsdfCount; ++i)
result += m_bsdfs[i]->fDelta(bRec) * m_bsdfWeight[i];
} else {
/* Pick out an individual component */
for (int i=0; i<m_bsdfCount; ++i) {
int component = bRec.component - m_bsdfOffset[i];
if (component < 0 || component >= m_bsdfs[i]->getComponentCount())
continue;
BSDFQueryRecord bRec2(bRec);
bRec2.component = component;
return m_bsdfs[i]->fDelta(bRec2) * m_bsdfWeight[i];
}
}
return result;
}
Float pdf(const BSDFQueryRecord &bRec) const { Float pdf(const BSDFQueryRecord &bRec) const {
Float result = 0.0f; Float result = 0.0f;
@ -153,6 +174,28 @@ public:
return result; return result;
} }
Float pdfDelta(const BSDFQueryRecord &bRec) const {
Float result = 0.0f;
if (bRec.component == -1) {
for (int i=0; i<m_bsdfCount; ++i)
result += m_bsdfs[i]->pdfDelta(bRec) * m_pdf[i];
} else {
/* Pick out an individual component */
for (int i=0; i<m_bsdfCount; ++i) {
int component = bRec.component - m_bsdfOffset[i];
if (component < 0 || component >= m_bsdfs[i]->getComponentCount())
continue;
BSDFQueryRecord bRec2(bRec);
bRec2.component = component;
return m_bsdfs[i]->pdfDelta(bRec2);
}
}
return result;
}
Spectrum sample(BSDFQueryRecord &bRec, Float &pdf) const { Spectrum sample(BSDFQueryRecord &bRec, Float &pdf) const {
if (bRec.component == -1) { if (bRec.component == -1) {
Float componentPDF; Float componentPDF;

View File

@ -13,19 +13,27 @@ class Phong : public BSDF {
public: public:
Phong(const Properties &props) Phong(const Properties &props)
: BSDF(props) { : BSDF(props) {
m_diffuseReflectance = new ConstantTexture( m_diffuseColor = new ConstantTexture(
props.getSpectrum("diffuseReflectance", Spectrum(.5f))); props.getSpectrum("diffuseColor", Spectrum(1.0f)));
m_specularReflectance = new ConstantTexture( m_specularColor = new ConstantTexture(
props.getSpectrum("specularReflectance", Spectrum(.2f))); props.getSpectrum("specularColor", Spectrum(1.0f)));
m_kd = m_diffuseReflectance->getAverage().average();
m_ks = m_specularReflectance->getAverage().average(); m_kd = props.getFloat("diffuseReflectance", 0.5f);
m_ks = props.getFloat("specularReflectance", 0.2f);
Float avgDiffReflectance = m_diffuseColor->getAverage().average() * m_kd;
Float avgSpecularReflectance = m_specularColor->getAverage().average() * m_ks;
m_specularSamplingWeight = props.getFloat("specularSamplingWeight", m_specularSamplingWeight = props.getFloat("specularSamplingWeight",
m_ks / (m_kd+m_ks)); avgSpecularReflectance / (avgDiffReflectance + avgSpecularReflectance));
m_diffuseSamplingWeight = 1.0f - m_specularSamplingWeight; m_diffuseSamplingWeight = 1.0f - m_specularSamplingWeight;
m_exponent = props.getFloat("exponent", 10.0f); m_exponent = props.getFloat("exponent", 10.0f);
if (m_kd + m_ks > 1.0f) if (m_kd * m_diffuseColor->getMaximum().max() + m_ks * m_specularColor->getMaximum().max() > 1.0f) {
Log(EWarn, "Energy conservation is violated!"); Log(EWarn, "%s: Energy conservation is violated!", props.getID().c_str());
Log(EWarn, "%s: Max. diffuse reflectance = %f * %f", m_kd, m_diffuseColor->getMaximum().max());
Log(EWarn, "%s: Max. specular reflectance = %f * %f", m_ks, m_specularColor->getMaximum().max());
}
m_componentCount = 2; m_componentCount = 2;
m_type = new unsigned int[m_componentCount]; m_type = new unsigned int[m_componentCount];
@ -37,8 +45,8 @@ public:
Phong(Stream *stream, InstanceManager *manager) Phong(Stream *stream, InstanceManager *manager)
: BSDF(stream, manager) { : BSDF(stream, manager) {
m_diffuseReflectance = static_cast<Texture *>(manager->getInstance(stream)); m_diffuseColor = static_cast<Texture *>(manager->getInstance(stream));
m_specularReflectance = static_cast<Texture *>(manager->getInstance(stream)); m_specularColor = static_cast<Texture *>(manager->getInstance(stream));
m_exponent = stream->readFloat(); m_exponent = stream->readFloat();
m_kd = stream->readFloat(); m_kd = stream->readFloat();
m_ks = stream->readFloat(); m_ks = stream->readFloat();
@ -51,8 +59,8 @@ public:
m_type[1] = EGlossyReflection; m_type[1] = EGlossyReflection;
m_combinedType = m_type[0] | m_type[1]; m_combinedType = m_type[0] | m_type[1];
m_usesRayDifferentials = m_usesRayDifferentials =
m_diffuseReflectance->usesRayDifferentials() || m_diffuseColor->usesRayDifferentials() ||
m_specularReflectance->usesRayDifferentials(); m_specularColor->usesRayDifferentials();
} }
virtual ~Phong() { virtual ~Phong() {
@ -60,7 +68,7 @@ public:
} }
Spectrum getDiffuseReflectance(const Intersection &its) const { Spectrum getDiffuseReflectance(const Intersection &its) const {
return m_diffuseReflectance->getValue(its); return m_diffuseColor->getValue(its) * m_kd;
} }
Spectrum f(const BSDFQueryRecord &bRec) const { Spectrum f(const BSDFQueryRecord &bRec) const {
@ -83,12 +91,12 @@ public:
specRef = 0.0f; specRef = 0.0f;
else else
specRef = (m_exponent + 2) * INV_TWOPI specRef = (m_exponent + 2) * INV_TWOPI
* std::pow(alpha, m_exponent); * std::pow(alpha, m_exponent) * m_ks;
result += m_specularReflectance->getValue(bRec.its) * specRef; result += m_specularColor->getValue(bRec.its) * specRef;
} }
if (hasDiffuse) if (hasDiffuse)
result += m_diffuseReflectance->getValue(bRec.its) * INV_PI; result += m_diffuseColor->getValue(bRec.its) * (INV_PI * m_kd);
return result; return result;
} }
@ -144,12 +152,8 @@ public:
if (bRec.wo.z <= 0) if (bRec.wo.z <= 0)
return Spectrum(0.0f); return Spectrum(0.0f);
if (m_diffuseSamplingWeight == 0) {
return m_specularReflectance->getValue(bRec.its) * (m_exponent+2)/(m_exponent+1);
} else {
return f(bRec) / pdf(bRec); return f(bRec) / pdf(bRec);
} }
}
inline Float pdfDiffuse(const BSDFQueryRecord &bRec) const { inline Float pdfDiffuse(const BSDFQueryRecord &bRec) const {
return Frame::cosTheta(bRec.wo) * INV_PI; return Frame::cosTheta(bRec.wo) * INV_PI;
@ -192,12 +196,12 @@ public:
} }
void addChild(const std::string &name, ConfigurableObject *child) { void addChild(const std::string &name, ConfigurableObject *child) {
if (child->getClass()->derivesFrom(Texture::m_theClass) && name == "diffuseReflectance") { if (child->getClass()->derivesFrom(Texture::m_theClass) && name == "diffuseColor") {
m_diffuseReflectance = static_cast<Texture *>(child); m_diffuseColor = static_cast<Texture *>(child);
m_usesRayDifferentials |= m_diffuseReflectance->usesRayDifferentials(); m_usesRayDifferentials |= m_diffuseColor->usesRayDifferentials();
} else if (child->getClass()->derivesFrom(Texture::m_theClass) && name == "specularReflectance") { } else if (child->getClass()->derivesFrom(Texture::m_theClass) && name == "specularColor") {
m_specularReflectance = static_cast<Texture *>(child); m_specularColor = static_cast<Texture *>(child);
m_usesRayDifferentials |= m_specularReflectance->usesRayDifferentials(); m_usesRayDifferentials |= m_specularColor->usesRayDifferentials();
} else { } else {
BSDF::addChild(name, child); BSDF::addChild(name, child);
} }
@ -206,8 +210,8 @@ public:
void serialize(Stream *stream, InstanceManager *manager) const { void serialize(Stream *stream, InstanceManager *manager) const {
BSDF::serialize(stream, manager); BSDF::serialize(stream, manager);
manager->serialize(stream, m_diffuseReflectance.get()); manager->serialize(stream, m_diffuseColor.get());
manager->serialize(stream, m_specularReflectance.get()); manager->serialize(stream, m_specularColor.get());
stream->writeFloat(m_exponent); stream->writeFloat(m_exponent);
stream->writeFloat(m_kd); stream->writeFloat(m_kd);
stream->writeFloat(m_ks); stream->writeFloat(m_ks);
@ -220,8 +224,8 @@ public:
std::string toString() const { std::string toString() const {
std::ostringstream oss; std::ostringstream oss;
oss << "Phong[" oss << "Phong["
<< " diffuseReflectance = " << indent(m_diffuseReflectance->toString()) << "," << endl << " diffuseColor = " << indent(m_diffuseColor->toString()) << "," << endl
<< " specularReflectance = " << indent(m_specularReflectance->toString()) << "," << endl << " specularColor = " << indent(m_specularColor->toString()) << "," << endl
<< " exponent = " << m_exponent << endl << " exponent = " << m_exponent << endl
<< "]"; << "]";
return oss.str(); return oss.str();
@ -230,8 +234,8 @@ public:
MTS_DECLARE_CLASS() MTS_DECLARE_CLASS()
private: private:
ref<Texture> m_diffuseReflectance; ref<Texture> m_diffuseColor;
ref<Texture> m_specularReflectance; ref<Texture> m_specularColor;
Float m_exponent; Float m_exponent;
Float m_kd, m_ks; Float m_kd, m_ks;
Float m_specularSamplingWeight; Float m_specularSamplingWeight;
@ -243,35 +247,39 @@ private:
class PhongShader : public Shader { class PhongShader : public Shader {
public: public:
PhongShader(Renderer *renderer, PhongShader(Renderer *renderer,
const Texture *diffuseReflectance, const Texture *diffuseColor,
const Texture *specularReflectance, const Texture *specularColor,
Float ks, Float kd,
Float exponent) : Shader(renderer, EBSDFShader), Float exponent) : Shader(renderer, EBSDFShader),
m_diffuseReflectance(diffuseReflectance), m_diffuseColor(diffuseColor),
m_specularReflectance(specularReflectance), m_specularColor(specularColor),
m_ks(ks), m_kd(kd),
m_exponent(exponent) { m_exponent(exponent) {
m_diffuseReflectanceShader = renderer->registerShaderForResource(m_diffuseReflectance.get()); m_diffuseColorShader = renderer->registerShaderForResource(m_diffuseColor.get());
m_specularReflectanceShader = renderer->registerShaderForResource(m_specularReflectance.get()); m_specularColorShader = renderer->registerShaderForResource(m_specularColor.get());
} }
bool isComplete() const { bool isComplete() const {
return m_diffuseReflectanceShader.get() != NULL && return m_diffuseColorShader.get() != NULL &&
m_specularReflectanceShader.get() != NULL; m_specularColorShader.get() != NULL;
} }
void putDependencies(std::vector<Shader *> &deps) { void putDependencies(std::vector<Shader *> &deps) {
deps.push_back(m_diffuseReflectanceShader.get()); deps.push_back(m_diffuseColorShader.get());
deps.push_back(m_specularReflectanceShader.get()); deps.push_back(m_specularColorShader.get());
} }
void cleanup(Renderer *renderer) { void cleanup(Renderer *renderer) {
renderer->unregisterShaderForResource(m_diffuseReflectance.get()); renderer->unregisterShaderForResource(m_diffuseColor.get());
renderer->unregisterShaderForResource(m_specularReflectance.get()); renderer->unregisterShaderForResource(m_specularColor.get());
} }
void generateCode(std::ostringstream &oss, void generateCode(std::ostringstream &oss,
const std::string &evalName, const std::string &evalName,
const std::vector<std::string> &depNames) const { const std::vector<std::string> &depNames) const {
oss << "uniform float " << evalName << "_exponent;" << endl oss << "uniform float " << evalName << "_exponent;" << endl
<< "uniform float " << evalName << "_ks;" << endl
<< "uniform float " << evalName << "_kd;" << endl
<< endl << endl
<< "vec3 " << evalName << "(vec2 uv, vec3 wi, vec3 wo) {" << endl << "vec3 " << evalName << "(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " if (wi.z < 0.0 || wo.z < 0.0)" << endl << " if (wi.z < 0.0 || wo.z < 0.0)" << endl
@ -281,32 +289,37 @@ public:
<< " if (alpha < 0.0)" << endl << " if (alpha < 0.0)" << endl
<< " return vec3(0.0);" << endl << " return vec3(0.0);" << endl
<< " float specRef = pow(alpha, " << evalName << "_exponent) * " << endl << " float specRef = pow(alpha, " << evalName << "_exponent) * " << endl
<< " (" << evalName << "_exponent + 2) * 0.15915;" << endl << " (" << evalName << "_exponent + 2) * 0.15915 * " << evalName << "_ks;" << endl
<< " return " << depNames[0] << "(uv) * 0.31831" << endl << " return " << depNames[0] << "(uv) * (0.31831 * " << evalName << "_kd)" << endl
<< " + " << depNames[1] << "(uv) * specRef;" << endl << " + " << depNames[1] << "(uv) * specRef;" << endl
<< "}" << endl; << "}" << endl;
} }
void resolve(const GPUProgram *program, const std::string &evalName, std::vector<int> &parameterIDs) const { void resolve(const GPUProgram *program, const std::string &evalName, std::vector<int> &parameterIDs) const {
parameterIDs.push_back(program->getParameterID(evalName + "_exponent")); parameterIDs.push_back(program->getParameterID(evalName + "_exponent"));
parameterIDs.push_back(program->getParameterID(evalName + "_ks"));
parameterIDs.push_back(program->getParameterID(evalName + "_kd"));
} }
void bind(GPUProgram *program, const std::vector<int> &parameterIDs, int &textureUnitOffset) const { void bind(GPUProgram *program, const std::vector<int> &parameterIDs, int &textureUnitOffset) const {
program->setParameter(parameterIDs[0], m_exponent); program->setParameter(parameterIDs[0], m_exponent);
program->setParameter(parameterIDs[1], m_ks);
program->setParameter(parameterIDs[2], m_kd);
} }
MTS_DECLARE_CLASS() MTS_DECLARE_CLASS()
private: private:
ref<const Texture> m_diffuseReflectance; ref<const Texture> m_diffuseColor;
ref<const Texture> m_specularReflectance; ref<const Texture> m_specularColor;
ref<Shader> m_diffuseReflectanceShader; ref<Shader> m_diffuseColorShader;
ref<Shader> m_specularReflectanceShader; ref<Shader> m_specularColorShader;
Float m_ks, m_kd;
Float m_exponent; Float m_exponent;
}; };
Shader *Phong::createShader(Renderer *renderer) const { Shader *Phong::createShader(Renderer *renderer) const {
return new PhongShader(renderer, m_diffuseReflectance.get(), return new PhongShader(renderer, m_diffuseColor.get(),
m_specularReflectance.get(), m_exponent); m_specularColor.get(), m_ks, m_kd, m_exponent);
} }
MTS_IMPLEMENT_CLASS(PhongShader, false, Shader) MTS_IMPLEMENT_CLASS(PhongShader, false, Shader)

View File

@ -120,6 +120,12 @@ public:
void findRemovals(DOMNode *node, std::set<std::string> &removals) { void findRemovals(DOMNode *node, std::set<std::string> &removals) {
if (node) { if (node) {
char *nodeName = XMLString::transcode(node->getNodeName());
if (strcmp(nodeName, "ref") == 0) {
XMLString::release(&nodeName);
return;
}
XMLString::release(&nodeName);
if (node->getNodeType() == DOMNode::ELEMENT_NODE && node->hasAttributes()) { if (node->getNodeType() == DOMNode::ELEMENT_NODE && node->hasAttributes()) {
DOMNamedNodeMap *attributes = node->getAttributes(); DOMNamedNodeMap *attributes = node->getAttributes();
for (size_t i=0; i<attributes->getLength(); ++i) { for (size_t i=0; i<attributes->getLength(); ++i) {
@ -600,11 +606,13 @@ void loadMaterial(ColladaConverter *cvt, std::ostream &os, domMaterial &mat, Str
os << "\t</bsdf>" << endl << endl; os << "\t</bsdf>" << endl << endl;
} else { } else {
os << "\t<bsdf id=\"" << mat.getId() << "\" type=\"phong\">" << endl; os << "\t<bsdf id=\"" << mat.getId() << "\" type=\"phong\">" << endl;
loadMaterialParam(cvt, os, "diffuseReflectance", idToTexture, diffuse, false); os << "\t\t<float name=\"specularReflectance\" value=\"1\"/>" << endl;
loadMaterialParam(cvt, os, "specularReflectance", idToTexture, specular, false); os << "\t\t<float name=\"diffuseReflectance\" value=\"1\"/>" << endl;
loadMaterialParam(cvt, os, "diffuseColor", idToTexture, diffuse, false);
loadMaterialParam(cvt, os, "specularColor", idToTexture, specular, false);
loadMaterialParam(cvt, os, "exponent", idToTexture, shininess, false); loadMaterialParam(cvt, os, "exponent", idToTexture, shininess, false);
loadMaterialParam(cvt, os, "diffuseReflectance", idToTexture, diffuse, true); loadMaterialParam(cvt, os, "diffuseColor", idToTexture, diffuse, true);
loadMaterialParam(cvt, os, "specularReflectance", idToTexture, specular, true); loadMaterialParam(cvt, os, "specularColor", idToTexture, specular, true);
loadMaterialParam(cvt, os, "exponent", idToTexture, shininess, true); loadMaterialParam(cvt, os, "exponent", idToTexture, shininess, true);
os << "\t</bsdf>" << endl << endl; os << "\t</bsdf>" << endl << endl;
} }

View File

@ -103,6 +103,21 @@ MIPMap::~MIPMap() {
delete[] m_pyramid; delete[] m_pyramid;
} }
Spectrum MIPMap::getMaximum() const {
Spectrum max(0.0f);
int height = m_levelHeight[0];
int width = m_levelWidth[0];
Spectrum *pixels = m_pyramid[0];
for (int y=0; y<height; ++y) {
for (int x=0; x<width; ++x) {
Spectrum value = *pixels++;
for (int j=0; j<SPECTRUM_SAMPLES; ++j)
max[j] = std::max(max[j], value[j]);
}
}
return max;
}
ref<MIPMap> MIPMap::fromBitmap(Bitmap *bitmap) { ref<MIPMap> MIPMap::fromBitmap(Bitmap *bitmap) {
int width = bitmap->getWidth(); int width = bitmap->getWidth();
int height = bitmap->getHeight(); int height = bitmap->getHeight();

View File

@ -79,6 +79,8 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
ParseContext &context = m_context.top(); ParseContext &context = m_context.top();
std::string type = context.attributes["type"]; std::string type = context.attributes["type"];
context.properties.setPluginName(type); context.properties.setPluginName(type);
if (context.attributes.find("id") != context.attributes.end())
context.properties.setID(context.attributes["id"]);
ref<ConfigurableObject> object = NULL; ref<ConfigurableObject> object = NULL;

View File

@ -38,6 +38,10 @@ public:
return m_reflectance * .5f; return m_reflectance * .5f;
} }
Spectrum getMaximum() const {
return m_reflectance;
}
std::string toString() const { std::string toString() const {
return "Checkerboard[]"; return "Checkerboard[]";
} }

View File

@ -21,6 +21,7 @@ public:
ref<Bitmap> bitmap = new Bitmap(Bitmap::EEXR, fs); ref<Bitmap> bitmap = new Bitmap(Bitmap::EEXR, fs);
m_mipmap = MIPMap::fromBitmap(bitmap); m_mipmap = MIPMap::fromBitmap(bitmap);
m_average = m_mipmap->triangle(m_mipmap->getLevels()-1, 0, 0); m_average = m_mipmap->triangle(m_mipmap->getLevels()-1, 0, 0);
m_maximum = m_mipmap->getMaximum();
} }
EXRTexture(Stream *stream, InstanceManager *manager) EXRTexture(Stream *stream, InstanceManager *manager)
@ -34,6 +35,7 @@ public:
ref<Bitmap> bitmap = new Bitmap(Bitmap::EEXR, mStream); ref<Bitmap> bitmap = new Bitmap(Bitmap::EEXR, mStream);
m_mipmap = MIPMap::fromBitmap(bitmap); m_mipmap = MIPMap::fromBitmap(bitmap);
m_average = m_mipmap->triangle(m_mipmap->getLevels()-1, 0, 0); m_average = m_mipmap->triangle(m_mipmap->getLevels()-1, 0, 0);
m_maximum = m_mipmap->getMaximum();
} }
void serialize(Stream *stream, InstanceManager *manager) const { void serialize(Stream *stream, InstanceManager *manager) const {
@ -48,6 +50,10 @@ public:
return m_mipmap->getValue(its); return m_mipmap->getValue(its);
} }
Spectrum getMaximum() const {
return m_maximum;
}
Spectrum getAverage() const { Spectrum getAverage() const {
return m_average; return m_average;
} }
@ -66,7 +72,7 @@ public:
protected: protected:
ref<MIPMap> m_mipmap; ref<MIPMap> m_mipmap;
std::string m_filename; std::string m_filename;
Spectrum m_average; Spectrum m_average, m_maximum;
}; };
MTS_IMPLEMENT_CLASS_S(EXRTexture, false, Texture) MTS_IMPLEMENT_CLASS_S(EXRTexture, false, Texture)

View File

@ -41,10 +41,14 @@ public:
return false; return false;
} }
Spectrum getAverage() const { Spectrum getMaximum() const {
return m_reflectance; return m_reflectance;
} }
Spectrum getAverage() const {
return m_reflectance; // that's not quite right
}
std::string toString() const { std::string toString() const {
return "GridTexture[]"; return "GridTexture[]";
} }

View File

@ -175,6 +175,7 @@ public:
m_mipmap = MIPMap::fromBitmap(corrected); m_mipmap = MIPMap::fromBitmap(corrected);
m_average = m_mipmap->triangle(m_mipmap->getLevels()-1, 0, 0); m_average = m_mipmap->triangle(m_mipmap->getLevels()-1, 0, 0);
m_maximum = m_mipmap->getMaximum();
} }
void serialize(Stream *stream, InstanceManager *manager) const { void serialize(Stream *stream, InstanceManager *manager) const {
@ -201,6 +202,10 @@ public:
return m_average; return m_average;
} }
Spectrum getMaximum() const {
return m_maximum;
}
bool usesRayDifferentials() const { bool usesRayDifferentials() const {
return true; return true;
} }
@ -219,7 +224,7 @@ protected:
ref<MemoryStream> m_stream; ref<MemoryStream> m_stream;
std::string m_filename; std::string m_filename;
Bitmap::EFileFormat m_format; Bitmap::EFileFormat m_format;
Spectrum m_average; Spectrum m_average, m_maximum;
Float m_gamma; Float m_gamma;
}; };