BMP loading support, material parameter naming more uniform
parent
d4181b01fd
commit
d4ae5660cf
|
@ -40,9 +40,30 @@ public:
|
||||||
props.getSpectrum("diffuseReflectance", Spectrum(0.0f)));
|
props.getSpectrum("diffuseReflectance", Spectrum(0.0f)));
|
||||||
m_specularReflectance = new ConstantTexture(
|
m_specularReflectance = new ConstantTexture(
|
||||||
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
||||||
|
|
||||||
|
m_kd = props.getFloat("diffuseAmount", 1.0f);
|
||||||
|
m_ks = props.getFloat("specularAmount", 1.0f);
|
||||||
|
|
||||||
|
bool verifyEnergyConservation = props.getBoolean("verifyEnergyConservation", true);
|
||||||
|
|
||||||
|
if (verifyEnergyConservation && (m_kd * m_diffuseReflectance->getMaximum().max()
|
||||||
|
+ m_ks * m_specularReflectance->getMaximum().max() > 1.0f)) {
|
||||||
|
Log(EWarn, "%s: Energy conservation is potentially violated!", props.getID().c_str());
|
||||||
|
Log(EWarn, "Max. diffuse reflectance = %f * %f = %f", m_kd, m_diffuseReflectance->getMaximum().max(), m_kd*m_diffuseReflectance->getMaximum().max());
|
||||||
|
Log(EWarn, "Max. specular reflectance = %f * %f = %f", m_ks, m_specularReflectance->getMaximum().max(), m_ks*m_specularReflectance->getMaximum().max());
|
||||||
|
Float normalization = 1/(m_kd * m_diffuseReflectance->getMaximum().max() + m_ks * m_specularReflectance->getMaximum().max());
|
||||||
|
Log(EWarn, "Reducing the albedo to %.1f%% of the original value to be on the safe side. "
|
||||||
|
"Specify verifyEnergyConservation=false to prevent this.", normalization * 100);
|
||||||
|
m_kd *= normalization; m_ks *= normalization;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float avgDiffReflectance = m_diffuseReflectance->getAverage().average() * m_kd;
|
||||||
|
Float avgSpecularReflectance = m_specularReflectance->getAverage().average() * m_ks;
|
||||||
|
|
||||||
m_specularSamplingWeight = props.getFloat("specularSamplingWeight",
|
m_specularSamplingWeight = props.getFloat("specularSamplingWeight",
|
||||||
std::max((Float) 0.3, 1-2*m_diffuseReflectance->getAverage().average()));
|
avgSpecularReflectance / (avgDiffReflectance + avgSpecularReflectance));
|
||||||
m_diffuseSamplingWeight = 1.0f - m_specularSamplingWeight;
|
m_diffuseSamplingWeight = 1.0f - m_specularSamplingWeight;
|
||||||
|
|
||||||
m_alphaB = props.getFloat("alphaB", .1f);
|
m_alphaB = props.getFloat("alphaB", .1f);
|
||||||
m_intIOR = props.getFloat("intIOR", 1.5f);
|
m_intIOR = props.getFloat("intIOR", 1.5f);
|
||||||
m_extIOR = props.getFloat("extIOR", 1.0f);
|
m_extIOR = props.getFloat("extIOR", 1.0f);
|
||||||
|
@ -62,6 +83,8 @@ public:
|
||||||
m_diffuseReflectance = static_cast<Texture *>(manager->getInstance(stream));
|
m_diffuseReflectance = static_cast<Texture *>(manager->getInstance(stream));
|
||||||
m_specularReflectance = static_cast<Texture *>(manager->getInstance(stream));
|
m_specularReflectance = static_cast<Texture *>(manager->getInstance(stream));
|
||||||
m_alphaB = stream->readFloat();
|
m_alphaB = stream->readFloat();
|
||||||
|
m_kd = stream->readFloat();
|
||||||
|
m_ks = stream->readFloat();
|
||||||
m_intIOR = stream->readFloat();
|
m_intIOR = stream->readFloat();
|
||||||
m_extIOR = stream->readFloat();
|
m_extIOR = stream->readFloat();
|
||||||
m_specularSamplingWeight = stream->readFloat();
|
m_specularSamplingWeight = stream->readFloat();
|
||||||
|
@ -82,7 +105,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Spectrum getDiffuseReflectance(const Intersection &its) const {
|
Spectrum getDiffuseReflectance(const Intersection &its) const {
|
||||||
return m_diffuseReflectance->getValue(its);
|
return m_diffuseReflectance->getValue(its) * m_kd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -162,9 +185,9 @@ public:
|
||||||
Float F = fresnel(dot(bRec.wi, Hr), m_extIOR, m_intIOR);
|
Float F = fresnel(dot(bRec.wi, Hr), m_extIOR, m_intIOR);
|
||||||
|
|
||||||
if (hasGlossy)
|
if (hasGlossy)
|
||||||
result += fSpec(bRec, Hr) * F;
|
result += fSpec(bRec, Hr) * (F * m_ks);
|
||||||
if (hasDiffuse)
|
if (hasDiffuse)
|
||||||
result += m_diffuseReflectance->getValue(bRec.its) * INV_PI * (1-F);
|
result += m_diffuseReflectance->getValue(bRec.its) * (INV_PI * (1-F) * m_kd);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -268,6 +291,8 @@ public:
|
||||||
manager->serialize(stream, m_diffuseReflectance.get());
|
manager->serialize(stream, m_diffuseReflectance.get());
|
||||||
manager->serialize(stream, m_specularReflectance.get());
|
manager->serialize(stream, m_specularReflectance.get());
|
||||||
stream->writeFloat(m_alphaB);
|
stream->writeFloat(m_alphaB);
|
||||||
|
stream->writeFloat(m_kd);
|
||||||
|
stream->writeFloat(m_ks);
|
||||||
stream->writeFloat(m_intIOR);
|
stream->writeFloat(m_intIOR);
|
||||||
stream->writeFloat(m_extIOR);
|
stream->writeFloat(m_extIOR);
|
||||||
stream->writeFloat(m_specularSamplingWeight);
|
stream->writeFloat(m_specularSamplingWeight);
|
||||||
|
@ -295,6 +320,7 @@ private:
|
||||||
Float m_alphaB, m_intIOR, m_extIOR;
|
Float m_alphaB, m_intIOR, m_extIOR;
|
||||||
Float m_specularSamplingWeight;
|
Float m_specularSamplingWeight;
|
||||||
Float m_diffuseSamplingWeight;
|
Float m_diffuseSamplingWeight;
|
||||||
|
Float m_ks, m_kd;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ================ Hardware shader implementation ================
|
// ================ Hardware shader implementation ================
|
||||||
|
@ -304,10 +330,12 @@ public:
|
||||||
MicrofacetShader(Renderer *renderer,
|
MicrofacetShader(Renderer *renderer,
|
||||||
const Texture *diffuseReflectance,
|
const Texture *diffuseReflectance,
|
||||||
const Texture *specularReflectance,
|
const Texture *specularReflectance,
|
||||||
Float alphaB, Float etaInt, Float etaExt) : Shader(renderer, EBSDFShader),
|
Float alphaB, Float etaInt, Float etaExt,
|
||||||
|
Float ks, Float kd) : Shader(renderer, EBSDFShader),
|
||||||
m_diffuseReflectance(diffuseReflectance),
|
m_diffuseReflectance(diffuseReflectance),
|
||||||
m_specularReflectance(specularReflectance),
|
m_specularReflectance(specularReflectance),
|
||||||
m_alphaB(alphaB), m_etaInt(etaInt), m_etaExt(etaExt) {
|
m_alphaB(alphaB), m_etaInt(etaInt), m_etaExt(etaExt),
|
||||||
|
m_ks(ks), m_kd(kd) {
|
||||||
m_diffuseReflectanceShader = renderer->registerShaderForResource(m_diffuseReflectance.get());
|
m_diffuseReflectanceShader = renderer->registerShaderForResource(m_diffuseReflectance.get());
|
||||||
m_specularReflectanceShader = renderer->registerShaderForResource(m_specularReflectance.get());
|
m_specularReflectanceShader = renderer->registerShaderForResource(m_specularReflectance.get());
|
||||||
}
|
}
|
||||||
|
@ -333,6 +361,8 @@ public:
|
||||||
oss << "uniform float " << evalName << "_alphaB;" << endl
|
oss << "uniform float " << evalName << "_alphaB;" << endl
|
||||||
<< "uniform float " << evalName << "_etaInt;" << endl
|
<< "uniform float " << evalName << "_etaInt;" << endl
|
||||||
<< "uniform float " << evalName << "_etaExt;" << endl
|
<< "uniform float " << evalName << "_etaExt;" << endl
|
||||||
|
<< "uniform float " << evalName << "_ks;" << endl
|
||||||
|
<< "uniform float " << evalName << "_kd;" << endl
|
||||||
<< endl
|
<< endl
|
||||||
<< "float " << evalName << "_beckmannD(vec3 m) {" << endl
|
<< "float " << evalName << "_beckmannD(vec3 m) {" << endl
|
||||||
<< " float ex = tanTheta(m) / " << evalName << "_alphaB;" << endl
|
<< " float ex = tanTheta(m) / " << evalName << "_alphaB;" << endl
|
||||||
|
@ -376,8 +406,8 @@ public:
|
||||||
<< " vec3 hr = normalize(wi + wo);" << endl
|
<< " vec3 hr = normalize(wi + wo);" << endl
|
||||||
<< " float Fr = " << evalName << "_fresnel(wi, hr, " << evalName << "_etaExt, " << evalName << "_etaInt);"<< endl
|
<< " float Fr = " << evalName << "_fresnel(wi, hr, " << evalName << "_etaExt, " << evalName << "_etaInt);"<< endl
|
||||||
<< " float Ft = 1-Fr;"<< endl
|
<< " float Ft = 1-Fr;"<< endl
|
||||||
<< " return " << depNames[0] << "(uv) * (0.31831 * Ft)" << endl
|
<< " return " << depNames[0] << "(uv) * (0.31831 * Ft) * " << evalName << "_kd" << endl
|
||||||
<< " + " << depNames[1] << "(uv) * (" << evalName << "_fSpec(wi, wo, hr) * Fr);" << endl
|
<< " + " << depNames[1] << "(uv) * (" << evalName << "_fSpec(wi, wo, hr) * Fr) * " << evalName << "_ks" << endl
|
||||||
<< "}" << endl
|
<< "}" << endl
|
||||||
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl
|
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl
|
||||||
<< " if (wi.z <= 0 || wo.z <= 0)" << endl
|
<< " if (wi.z <= 0 || wo.z <= 0)" << endl
|
||||||
|
@ -390,12 +420,16 @@ public:
|
||||||
parameterIDs.push_back(program->getParameterID(evalName + "_alphaB", false));
|
parameterIDs.push_back(program->getParameterID(evalName + "_alphaB", false));
|
||||||
parameterIDs.push_back(program->getParameterID(evalName + "_etaInt", false));
|
parameterIDs.push_back(program->getParameterID(evalName + "_etaInt", false));
|
||||||
parameterIDs.push_back(program->getParameterID(evalName + "_etaExt", false));
|
parameterIDs.push_back(program->getParameterID(evalName + "_etaExt", false));
|
||||||
|
parameterIDs.push_back(program->getParameterID(evalName + "_ks", false));
|
||||||
|
parameterIDs.push_back(program->getParameterID(evalName + "_kd", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(GPUProgram *program, const std::vector<int> ¶meterIDs, int &textureUnitOffset) const {
|
void bind(GPUProgram *program, const std::vector<int> ¶meterIDs, int &textureUnitOffset) const {
|
||||||
program->setParameter(parameterIDs[0], m_alphaB);
|
program->setParameter(parameterIDs[0], m_alphaB);
|
||||||
program->setParameter(parameterIDs[1], m_etaInt);
|
program->setParameter(parameterIDs[1], m_etaInt);
|
||||||
program->setParameter(parameterIDs[2], m_etaExt);
|
program->setParameter(parameterIDs[2], m_etaExt);
|
||||||
|
program->setParameter(parameterIDs[3], m_ks);
|
||||||
|
program->setParameter(parameterIDs[4], m_kd);
|
||||||
}
|
}
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
|
@ -404,12 +438,13 @@ private:
|
||||||
ref<const Texture> m_specularReflectance;
|
ref<const Texture> m_specularReflectance;
|
||||||
ref<Shader> m_diffuseReflectanceShader;
|
ref<Shader> m_diffuseReflectanceShader;
|
||||||
ref<Shader> m_specularReflectanceShader;
|
ref<Shader> m_specularReflectanceShader;
|
||||||
Float m_alphaB, m_etaInt, m_etaExt;
|
Float m_alphaB, m_etaInt, m_etaExt, m_ks, m_kd;
|
||||||
};
|
};
|
||||||
|
|
||||||
Shader *Microfacet::createShader(Renderer *renderer) const {
|
Shader *Microfacet::createShader(Renderer *renderer) const {
|
||||||
return new MicrofacetShader(renderer, m_diffuseReflectance.get(),
|
return new MicrofacetShader(renderer, m_diffuseReflectance.get(),
|
||||||
m_specularReflectance.get(), m_alphaB, m_intIOR, m_extIOR);
|
m_specularReflectance.get(), m_alphaB, m_intIOR, m_extIOR,
|
||||||
|
m_ks, m_kd);
|
||||||
}
|
}
|
||||||
|
|
||||||
MTS_IMPLEMENT_CLASS(MicrofacetShader, false, Shader)
|
MTS_IMPLEMENT_CLASS(MicrofacetShader, false, Shader)
|
||||||
|
|
|
@ -31,27 +31,32 @@ class Phong : public BSDF {
|
||||||
public:
|
public:
|
||||||
Phong(const Properties &props)
|
Phong(const Properties &props)
|
||||||
: BSDF(props) {
|
: BSDF(props) {
|
||||||
m_diffuseColor = new ConstantTexture(
|
m_diffuseReflectance = new ConstantTexture(
|
||||||
props.getSpectrum("diffuseColor", Spectrum(1.0f)));
|
props.getSpectrum("diffuseReflectance", Spectrum(0.5f)));
|
||||||
m_specularColor = new ConstantTexture(
|
m_specularReflectance = new ConstantTexture(
|
||||||
props.getSpectrum("specularColor", Spectrum(1.0f)));
|
props.getSpectrum("specularReflectance", Spectrum(0.2f)));
|
||||||
|
|
||||||
|
m_kd = props.getFloat("diffuseAmount", 1.0f);
|
||||||
|
m_ks = props.getFloat("specularAmount", 1.0f);
|
||||||
|
|
||||||
m_kd = props.getFloat("diffuseReflectance", 0.5f);
|
|
||||||
m_ks = props.getFloat("specularReflectance", 0.2f);
|
|
||||||
m_exponent = props.getFloat("exponent", 10.0f);
|
m_exponent = props.getFloat("exponent", 10.0f);
|
||||||
|
|
||||||
if (m_kd * m_diffuseColor->getMaximum().max() + m_ks * m_specularColor->getMaximum().max() > 1.0f) {
|
bool verifyEnergyConservation = props.getBoolean("verifyEnergyConservation", true);
|
||||||
Log(EWarn, "%s: Energy conservation is violated!", props.getID().c_str());
|
|
||||||
Log(EWarn, "Max. diffuse reflectance = %f * %f", m_kd, m_diffuseColor->getMaximum().max());
|
if (verifyEnergyConservation && (m_kd * m_diffuseReflectance->getMaximum().max()
|
||||||
Log(EWarn, "Max. specular reflectance = %f * %f", m_ks, m_specularColor->getMaximum().max());
|
+ m_ks * m_specularReflectance->getMaximum().max() > 1.0f)) {
|
||||||
Float normalization = 1/(m_kd * m_diffuseColor->getMaximum().max() + m_ks * m_specularColor->getMaximum().max());
|
Log(EWarn, "%s: Energy conservation is potentially violated!", props.getID().c_str());
|
||||||
Log(EWarn, "Reducing the albedo to %.1f%% of the original value", normalization * 100);
|
Log(EWarn, "Max. diffuse reflectance = %f * %f = %f", m_kd, m_diffuseReflectance->getMaximum().max(), m_kd*m_diffuseReflectance->getMaximum().max());
|
||||||
|
Log(EWarn, "Max. specular reflectance = %f * %f = %f", m_ks, m_specularReflectance->getMaximum().max(), m_ks*m_specularReflectance->getMaximum().max());
|
||||||
|
Float normalization = 1/(m_kd * m_diffuseReflectance->getMaximum().max() + m_ks * m_specularReflectance->getMaximum().max());
|
||||||
|
Log(EWarn, "Reducing the albedo to %.1f%% of the original value to be on the safe side. "
|
||||||
|
"Specify verifyEnergyConservation=false to prevent this.", normalization * 100);
|
||||||
m_kd *= normalization; m_ks *= normalization;
|
m_kd *= normalization; m_ks *= normalization;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float avgDiffReflectance = m_diffuseColor->getAverage().average() * m_kd;
|
Float avgDiffReflectance = m_diffuseReflectance->getAverage().average() * m_kd;
|
||||||
Float avgSpecularReflectance = m_specularColor->getAverage().average() * m_ks;
|
Float avgSpecularReflectance = m_specularReflectance->getAverage().average() * m_ks;
|
||||||
|
|
||||||
m_specularSamplingWeight = props.getFloat("specularSamplingWeight",
|
m_specularSamplingWeight = props.getFloat("specularSamplingWeight",
|
||||||
avgSpecularReflectance / (avgDiffReflectance + avgSpecularReflectance));
|
avgSpecularReflectance / (avgDiffReflectance + avgSpecularReflectance));
|
||||||
m_diffuseSamplingWeight = 1.0f - m_specularSamplingWeight;
|
m_diffuseSamplingWeight = 1.0f - m_specularSamplingWeight;
|
||||||
|
@ -66,8 +71,8 @@ public:
|
||||||
|
|
||||||
Phong(Stream *stream, InstanceManager *manager)
|
Phong(Stream *stream, InstanceManager *manager)
|
||||||
: BSDF(stream, manager) {
|
: BSDF(stream, manager) {
|
||||||
m_diffuseColor = static_cast<Texture *>(manager->getInstance(stream));
|
m_diffuseReflectance = static_cast<Texture *>(manager->getInstance(stream));
|
||||||
m_specularColor = static_cast<Texture *>(manager->getInstance(stream));
|
m_specularReflectance = 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();
|
||||||
|
@ -80,8 +85,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_diffuseColor->usesRayDifferentials() ||
|
m_diffuseReflectance->usesRayDifferentials() ||
|
||||||
m_specularColor->usesRayDifferentials();
|
m_specularReflectance->usesRayDifferentials();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Phong() {
|
virtual ~Phong() {
|
||||||
|
@ -89,7 +94,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Spectrum getDiffuseReflectance(const Intersection &its) const {
|
Spectrum getDiffuseReflectance(const Intersection &its) const {
|
||||||
return m_diffuseColor->getValue(its) * m_kd;
|
return m_diffuseReflectance->getValue(its) * m_kd;
|
||||||
}
|
}
|
||||||
|
|
||||||
Spectrum f(const BSDFQueryRecord &bRec) const {
|
Spectrum f(const BSDFQueryRecord &bRec) const {
|
||||||
|
@ -113,11 +118,11 @@ public:
|
||||||
else
|
else
|
||||||
specRef = (m_exponent + 2) * INV_TWOPI
|
specRef = (m_exponent + 2) * INV_TWOPI
|
||||||
* std::pow(alpha, m_exponent) * m_ks;
|
* std::pow(alpha, m_exponent) * m_ks;
|
||||||
result += m_specularColor->getValue(bRec.its) * specRef;
|
result += m_specularReflectance->getValue(bRec.its) * specRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasDiffuse)
|
if (hasDiffuse)
|
||||||
result += m_diffuseColor->getValue(bRec.its) * (INV_PI * m_kd);
|
result += m_diffuseReflectance->getValue(bRec.its) * (INV_PI * m_kd);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +160,7 @@ public:
|
||||||
inline Spectrum sampleSpecular(BSDFQueryRecord &bRec) const {
|
inline Spectrum sampleSpecular(BSDFQueryRecord &bRec) const {
|
||||||
Vector R = Vector(-bRec.wi.x, -bRec.wi.y, bRec.wi.z);
|
Vector R = Vector(-bRec.wi.x, -bRec.wi.y, bRec.wi.z);
|
||||||
|
|
||||||
/* Sample a cosine lobe centered around the normal */
|
/* Sample from a Phong lobe centered around (0, 0, 1) */
|
||||||
Float sinAlpha = std::sqrt(1-std::pow(bRec.sample.y, 2/(m_exponent + 1)));
|
Float sinAlpha = std::sqrt(1-std::pow(bRec.sample.y, 2/(m_exponent + 1)));
|
||||||
Float cosAlpha = std::pow(bRec.sample.y, 1/(m_exponent + 1));
|
Float cosAlpha = std::pow(bRec.sample.y, 1/(m_exponent + 1));
|
||||||
Float phi = (2.0f * M_PI) * bRec.sample.x;
|
Float phi = (2.0f * M_PI) * bRec.sample.x;
|
||||||
|
@ -218,11 +223,11 @@ 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 == "diffuseColor") {
|
if (child->getClass()->derivesFrom(Texture::m_theClass) && name == "diffuseColor") {
|
||||||
m_diffuseColor = static_cast<Texture *>(child);
|
m_diffuseReflectance = static_cast<Texture *>(child);
|
||||||
m_usesRayDifferentials |= m_diffuseColor->usesRayDifferentials();
|
m_usesRayDifferentials |= m_diffuseReflectance->usesRayDifferentials();
|
||||||
} else if (child->getClass()->derivesFrom(Texture::m_theClass) && name == "specularColor") {
|
} else if (child->getClass()->derivesFrom(Texture::m_theClass) && name == "specularColor") {
|
||||||
m_specularColor = static_cast<Texture *>(child);
|
m_specularReflectance = static_cast<Texture *>(child);
|
||||||
m_usesRayDifferentials |= m_specularColor->usesRayDifferentials();
|
m_usesRayDifferentials |= m_specularReflectance->usesRayDifferentials();
|
||||||
} else {
|
} else {
|
||||||
BSDF::addChild(name, child);
|
BSDF::addChild(name, child);
|
||||||
}
|
}
|
||||||
|
@ -231,8 +236,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_diffuseColor.get());
|
manager->serialize(stream, m_diffuseReflectance.get());
|
||||||
manager->serialize(stream, m_specularColor.get());
|
manager->serialize(stream, m_specularReflectance.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);
|
||||||
|
@ -245,8 +250,8 @@ public:
|
||||||
std::string toString() const {
|
std::string toString() const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Phong[" << endl
|
oss << "Phong[" << endl
|
||||||
<< " diffuseColor = " << indent(m_diffuseColor->toString()) << "," << endl
|
<< " diffuseColor = " << indent(m_diffuseReflectance->toString()) << "," << endl
|
||||||
<< " specularColor = " << indent(m_specularColor->toString()) << "," << endl
|
<< " specularColor = " << indent(m_specularReflectance->toString()) << "," << endl
|
||||||
<< " exponent = " << m_exponent << endl
|
<< " exponent = " << m_exponent << endl
|
||||||
<< "]";
|
<< "]";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
|
@ -255,8 +260,8 @@ public:
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
private:
|
private:
|
||||||
ref<Texture> m_diffuseColor;
|
ref<Texture> m_diffuseReflectance;
|
||||||
ref<Texture> m_specularColor;
|
ref<Texture> m_specularReflectance;
|
||||||
Float m_exponent;
|
Float m_exponent;
|
||||||
Float m_kd, m_ks;
|
Float m_kd, m_ks;
|
||||||
Float m_specularSamplingWeight;
|
Float m_specularSamplingWeight;
|
||||||
|
@ -272,27 +277,27 @@ public:
|
||||||
const Texture *specularColor,
|
const Texture *specularColor,
|
||||||
Float ks, Float kd,
|
Float ks, Float kd,
|
||||||
Float exponent) : Shader(renderer, EBSDFShader),
|
Float exponent) : Shader(renderer, EBSDFShader),
|
||||||
m_diffuseColor(diffuseColor),
|
m_diffuseReflectance(diffuseColor),
|
||||||
m_specularColor(specularColor),
|
m_specularReflectance(specularColor),
|
||||||
m_ks(ks), m_kd(kd),
|
m_ks(ks), m_kd(kd),
|
||||||
m_exponent(exponent) {
|
m_exponent(exponent) {
|
||||||
m_diffuseColorShader = renderer->registerShaderForResource(m_diffuseColor.get());
|
m_diffuseReflectanceShader = renderer->registerShaderForResource(m_diffuseReflectance.get());
|
||||||
m_specularColorShader = renderer->registerShaderForResource(m_specularColor.get());
|
m_specularReflectanceShader = renderer->registerShaderForResource(m_specularReflectance.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isComplete() const {
|
bool isComplete() const {
|
||||||
return m_diffuseColorShader.get() != NULL &&
|
return m_diffuseReflectanceShader.get() != NULL &&
|
||||||
m_specularColorShader.get() != NULL;
|
m_specularReflectanceShader.get() != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void putDependencies(std::vector<Shader *> &deps) {
|
void putDependencies(std::vector<Shader *> &deps) {
|
||||||
deps.push_back(m_diffuseColorShader.get());
|
deps.push_back(m_diffuseReflectanceShader.get());
|
||||||
deps.push_back(m_specularColorShader.get());
|
deps.push_back(m_specularReflectanceShader.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup(Renderer *renderer) {
|
void cleanup(Renderer *renderer) {
|
||||||
renderer->unregisterShaderForResource(m_diffuseColor.get());
|
renderer->unregisterShaderForResource(m_diffuseReflectance.get());
|
||||||
renderer->unregisterShaderForResource(m_specularColor.get());
|
renderer->unregisterShaderForResource(m_specularReflectance.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateCode(std::ostringstream &oss,
|
void generateCode(std::ostringstream &oss,
|
||||||
|
@ -335,17 +340,17 @@ public:
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
private:
|
private:
|
||||||
ref<const Texture> m_diffuseColor;
|
ref<const Texture> m_diffuseReflectance;
|
||||||
ref<const Texture> m_specularColor;
|
ref<const Texture> m_specularReflectance;
|
||||||
ref<Shader> m_diffuseColorShader;
|
ref<Shader> m_diffuseReflectanceShader;
|
||||||
ref<Shader> m_specularColorShader;
|
ref<Shader> m_specularReflectanceShader;
|
||||||
Float m_ks, m_kd;
|
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_diffuseColor.get(),
|
return new PhongShader(renderer, m_diffuseReflectance.get(),
|
||||||
m_specularColor.get(), m_ks, m_kd, m_exponent);
|
m_specularReflectance.get(), m_ks, m_kd, m_exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
MTS_IMPLEMENT_CLASS(PhongShader, false, Shader)
|
MTS_IMPLEMENT_CLASS(PhongShader, false, Shader)
|
||||||
|
|
|
@ -613,13 +613,11 @@ void loadMaterial(GeometryConverter *cvt, std::ostream &os, domMaterial &mat, St
|
||||||
os << "\t</bsdf>" << endl << endl;
|
os << "\t</bsdf>" << endl << endl;
|
||||||
} else {
|
} else {
|
||||||
os << "\t<bsdf id=\"" << identifier << "\" type=\"phong\">" << endl;
|
os << "\t<bsdf id=\"" << identifier << "\" type=\"phong\">" << endl;
|
||||||
os << "\t\t<float name=\"specularReflectance\" value=\"1\"/>" << endl;
|
loadMaterialParam(cvt, os, "diffuseReflectance", idToTexture, diffuse, false);
|
||||||
os << "\t\t<float name=\"diffuseReflectance\" value=\"1\"/>" << endl;
|
loadMaterialParam(cvt, os, "specularReflectance", idToTexture, specular, false);
|
||||||
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, "diffuseColor", idToTexture, diffuse, true);
|
loadMaterialParam(cvt, os, "diffuseReflectance", idToTexture, diffuse, true);
|
||||||
loadMaterialParam(cvt, os, "specularColor", idToTexture, specular, true);
|
loadMaterialParam(cvt, os, "specularReflectance", 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,7 +268,7 @@ void Bitmap::loadBMP(Stream *stream) {
|
||||||
{
|
{
|
||||||
uint32_t header_sz;
|
uint32_t header_sz;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
int32_t height;
|
||||||
uint16_t nplanes;
|
uint16_t nplanes;
|
||||||
uint16_t bitspp;
|
uint16_t bitspp;
|
||||||
uint32_t compress_type;
|
uint32_t compress_type;
|
||||||
|
@ -301,17 +301,41 @@ void Bitmap::loadBMP(Stream *stream) {
|
||||||
if (DIBHeader.bitspp != 8 && DIBHeader.bitspp != 24)
|
if (DIBHeader.bitspp != 8 && DIBHeader.bitspp != 24)
|
||||||
Log(EError, "Only 8- and 24-bit BMP images are supported for now");
|
Log(EError, "Only 8- and 24-bit BMP images are supported for now");
|
||||||
|
|
||||||
|
if (DIBHeader.compress_type != 0)
|
||||||
|
Log(EError, "Only uncompressed BMP images are supported for now");
|
||||||
|
|
||||||
m_width = DIBHeader.width;
|
m_width = DIBHeader.width;
|
||||||
m_height = DIBHeader.height;
|
m_height = std::abs(DIBHeader.height);
|
||||||
m_bpp = DIBHeader.bitspp;
|
m_bpp = DIBHeader.bitspp;
|
||||||
|
|
||||||
m_size = m_width * m_height * (m_bpp / 8);
|
m_size = m_width * m_height * (m_bpp / 8);
|
||||||
m_data = static_cast<unsigned char *>(allocAligned(m_size));
|
m_data = static_cast<unsigned char *>(allocAligned(m_size));
|
||||||
|
Log(ETrace, "Reading %ix%ix%i BMP file", m_width, m_height, m_bpp);
|
||||||
|
|
||||||
Log(ETrace, "Reading %ix%ix%i PNG file", m_width, m_height, m_bpp);
|
int nChannels = m_bpp / 8;
|
||||||
|
int lineWidth = m_width * nChannels;
|
||||||
|
int paddedLineWidth = lineWidth + lineWidth % 4;
|
||||||
|
|
||||||
if (DIBHeader.compress_type != 0)
|
uint8_t *line = new uint8_t[paddedLineWidth];
|
||||||
Log(EError, "Only uncompressed BMP images are supported for now");
|
|
||||||
|
for (int y=0; y<m_height; ++y) {
|
||||||
|
stream->read(line, paddedLineWidth);
|
||||||
|
|
||||||
|
int targetY = y;
|
||||||
|
|
||||||
|
if (DIBHeader.height > 0)
|
||||||
|
targetY = m_height - 1 - y; // inverted rows
|
||||||
|
|
||||||
|
memcpy(&m_data[targetY * m_width * nChannels], line, lineWidth);
|
||||||
|
|
||||||
|
if (nChannels == 3) {
|
||||||
|
for (int x=0; x<m_width; ++x)
|
||||||
|
std::swap(m_data[(targetY * m_width + x) * nChannels],
|
||||||
|
m_data[(targetY * m_width + x) * nChannels + 2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] line;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::loadPNG(Stream *stream) {
|
void Bitmap::loadPNG(Stream *stream) {
|
||||||
|
|
Loading…
Reference in New Issue