diff --git a/src/bsdfs/composite.cpp b/src/bsdfs/composite.cpp index a3ebef44..f33171d1 100644 --- a/src/bsdfs/composite.cpp +++ b/src/bsdfs/composite.cpp @@ -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 &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 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; iunregisterShaderForResource(m_bsdfs[i]); + if (m_bsdfShader[i]) + m_bsdfShader[i]->decRef(); + } + m_bsdfShader.clear(); + } + + void putDependencies(std::vector &deps) { + for (size_t i=0; i &depNames) const { + Assert(m_complete); + int ctr = 0; + for (size_t i=0; i ¶meterIDs) const { + int ctr = 0; + for (size_t i=0; igetParameterID(formatString("%s_weight_%i", evalName.c_str(), ctr++))); + } + } + + void bind(GPUProgram *program, const std::vector ¶meterIDs, int &textureUnitOffset) const { + int ctr = 0; + for (size_t i=0; isetParameter(parameterIDs[ctr++], m_weights[i]); + } + } + + + MTS_DECLARE_CLASS() +private: + std::vector m_bsdfShader; + const std::vector &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 diff --git a/src/bsdfs/lambertian.cpp b/src/bsdfs/lambertian.cpp index 7df91f92..e8db43b6 100644 --- a/src/bsdfs/lambertian.cpp +++ b/src/bsdfs/lambertian.cpp @@ -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 diff --git a/src/libhw/renderer.cpp b/src/libhw/renderer.cpp index 5a982df1..703ed98c 100644 --- a/src/libhw/renderer.cpp +++ b/src/libhw/renderer.cpp @@ -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]; diff --git a/src/librender/scene.cpp b/src/librender/scene.cpp index 2643c98d..a283343c 100644 --- a/src/librender/scene.cpp +++ b/src/librender/scene.cpp @@ -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 */ diff --git a/src/luminaires/constant.cpp b/src/luminaires/constant.cpp index e6ce68f4..0835c0e3 100644 --- a/src/luminaires/constant.cpp +++ b/src/luminaires/constant.cpp @@ -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(); diff --git a/src/luminaires/envmap.cpp b/src/luminaires/envmap.cpp index 81e17ab8..4f5ad876 100644 --- a/src/luminaires/envmap.cpp +++ b/src/luminaires/envmap.cpp @@ -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();