composite material shader, do a better job at previewing environment sources

metadata
Wenzel Jakob 2010-08-18 23:19:54 +02:00
parent e1054035a3
commit 0d76becf5d
6 changed files with 115 additions and 8 deletions

View File

@ -264,6 +264,8 @@ public:
return oss.str();
}
Shader *createShader(Renderer *renderer) const;
MTS_DECLARE_CLASS()
private:
int m_bsdfCount;
@ -273,6 +275,107 @@ private:
DiscretePDF m_pdf;
};
// ================ Hardware shader implementation ================
class CompositeShader : public Shader {
public:
CompositeShader(Renderer *renderer, const std::vector<BSDF *> &bsdfs, Float *weights)
: Shader(renderer, EBSDFShader), m_bsdfs(bsdfs), m_weights(weights), m_complete(false) {
m_bsdfShader.resize(bsdfs.size());
for (size_t i=0; i<bsdfs.size(); ++i) {
ref<Shader> shader = renderer->registerShaderForResource(bsdfs[i]);
if (shader) {
shader->incRef();
/* At least one shader has a hardware implementation */
m_complete = true;
}
m_bsdfShader[i] = shader;
}
}
bool isComplete() const {
return m_complete;
}
void cleanup(Renderer *renderer) {
for (size_t i=0; i<m_bsdfs.size(); ++i) {
renderer->unregisterShaderForResource(m_bsdfs[i]);
if (m_bsdfShader[i])
m_bsdfShader[i]->decRef();
}
m_bsdfShader.clear();
}
void putDependencies(std::vector<Shader *> &deps) {
for (size_t i=0; i<m_bsdfs.size(); ++i) {
if (m_bsdfShader[i])
deps.push_back(m_bsdfShader[i]);
}
}
void generateCode(std::ostringstream &oss,
const std::string &evalName,
const std::vector<std::string> &depNames) const {
Assert(m_complete);
int ctr = 0;
for (size_t i=0; i<m_bsdfs.size(); ++i) {
if (!m_bsdfShader[i])
continue;
oss << "uniform float " << evalName << "_weight_" << ctr++ << ";" << endl;
}
oss << endl;
oss << "vec3 " << evalName << "(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " return ";
ctr = 0;
for (size_t i=0; i<m_bsdfs.size(); ++i) {
if (!m_bsdfShader[i])
continue;
oss << endl << " ";
if (ctr != 0)
oss << "+ ";
else
oss << " ";
oss << depNames[ctr] << "(uv, wi, wo) * "
<< evalName << "_weight_" << ctr;
ctr++;
}
oss << ";" << endl;
oss << "}" << endl;
}
void resolve(const GPUProgram *program, const std::string &evalName, std::vector<int> &parameterIDs) const {
int ctr = 0;
for (size_t i=0; i<m_bsdfs.size(); ++i) {
if (!m_bsdfShader[i])
continue;
parameterIDs.push_back(
program->getParameterID(formatString("%s_weight_%i", evalName.c_str(), ctr++)));
}
}
void bind(GPUProgram *program, const std::vector<int> &parameterIDs, int &textureUnitOffset) const {
int ctr = 0;
for (size_t i=0; i<m_bsdfs.size(); ++i) {
if (!m_bsdfShader[i])
continue;
program->setParameter(parameterIDs[ctr++], m_weights[i]);
}
}
MTS_DECLARE_CLASS()
private:
std::vector<Shader *> m_bsdfShader;
const std::vector<BSDF *> &m_bsdfs;
const Float *m_weights;
bool m_complete;
};
Shader *Composite::createShader(Renderer *renderer) const {
return new CompositeShader(renderer, m_bsdfs, m_bsdfWeight);
}
MTS_IMPLEMENT_CLASS(CompositeShader, false, Shader)
MTS_IMPLEMENT_CLASS_S(Composite, false, BSDF)
MTS_EXPORT_PLUGIN(Composite, "Composite BRDF");
MTS_EXPORT_PLUGIN(Composite, "Composite BRDF")
MTS_NAMESPACE_END

View File

@ -146,5 +146,5 @@ Shader *Lambertian::createShader(Renderer *renderer) const {
MTS_IMPLEMENT_CLASS(LambertianShader, false, Shader)
MTS_IMPLEMENT_CLASS_S(Lambertian, false, BSDF)
MTS_EXPORT_PLUGIN(Lambertian, "Lambertian BRDF");
MTS_EXPORT_PLUGIN(Lambertian, "Lambertian BRDF")
MTS_NAMESPACE_END

View File

@ -67,6 +67,8 @@ Shader *Renderer::getShaderForResource(const HWResource *resource) {
}
void Renderer::unregisterShaderForResource(const HWResource *resource) {
if (resource == NULL)
return;
if (m_shaders.find(resource) == m_shaders.end())
return;
ShaderRecord &sRec = m_shaders[resource];

View File

@ -243,7 +243,9 @@ void Scene::initialize() {
if (!m_luminairePDF.isReady()) {
if (m_luminaires.size() == 0) {
Log(EWarn, "No luminaires found -- adding a constant environment source");
addChild("", PluginManager::getInstance()->createObject(Luminaire::m_theClass, Properties("constant")));
Properties constantProps("constant");
constantProps.setSpectrum("intensity", Spectrum(0.5f));
addChild("", PluginManager::getInstance()->createObject(Luminaire::m_theClass, constantProps));
}
/* Calculate a discrete PDF to importance sample luminaires */

View File

@ -27,7 +27,7 @@ public:
void preprocess(const Scene *scene) {
/* Get the scene's bounding sphere and slightly enlarge it */
m_bsphere = scene->getBSphere();
m_bsphere.radius *= 2.0f;
m_bsphere.radius *= 1.01f;
m_surfaceArea = m_bsphere.radius * m_bsphere.radius * M_PI;
}
@ -114,7 +114,7 @@ public:
Float radius = m_bsphere.radius;
if (eRec.type == EmissionRecord::EPreview) {
/* This is more suitable for VPL-based rendering */
radius *= 10;
radius *= 1.5;
}
Vector d = squareToSphere(sample);
eRec.sRec.p = m_bsphere.center + d * radius;
@ -126,7 +126,7 @@ public:
Spectrum sampleEmissionDirection(EmissionRecord &eRec, const Point2 &sample) const {
Float radius = m_bsphere.radius;
if (eRec.type == EmissionRecord::EPreview)
radius *= 10;
radius *= 1.5f;
Point p2 = m_bsphere.center + squareToSphere(sample) * radius;
eRec.d = p2 - eRec.sRec.p;
Float length = eRec.d.length();

View File

@ -195,7 +195,7 @@ public:
} else {
/* Preview mode, which is more suitable for VPL-based rendering: approximate
the infinitely far-away source with set of diffuse point sources */
const Float radius = m_bsphere.radius * 10;
const Float radius = m_bsphere.radius * 1.5f;
Vector d = squareToSphere(sample);
eRec.sRec.p = m_bsphere.center + d * radius;
eRec.sRec.n = Normal(-d);
@ -207,7 +207,7 @@ public:
Spectrum sampleEmissionDirection(EmissionRecord &eRec, const Point2 &sample) const {
Float radius = m_bsphere.radius;
if (eRec.type == EmissionRecord::EPreview)
radius *= 10;
radius *= 1.5f;
Point p2 = m_bsphere.center + squareToSphere(sample) * radius;
eRec.d = p2 - eRec.sRec.p;
Float length = eRec.d.length();