composite material shader, do a better job at previewing environment sources
parent
e1054035a3
commit
0d76becf5d
|
@ -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> ¶meterIDs) 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> ¶meterIDs, 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue