starting to work on a directional luminaire

metadata
Wenzel Jakob 2010-08-12 20:13:34 +02:00
parent 0953ceaba3
commit 0d00364edc
4 changed files with 156 additions and 1 deletions

View File

@ -1,3 +1,10 @@
2010-08-12 Wenzel Jakob <wenzel@cs.cornell.edu>
* converter.cpp: Much better import of COLLADA scenes from
blender.
* importdlg.cpp: User interface for importing scenes.
2010-08-09 Wenzel Jakob <wenzel@cs.cornell.edu> 2010-08-09 Wenzel Jakob <wenzel@cs.cornell.edu>
* rendersettingsdlg.cpp: Try to maintain the number of * rendersettingsdlg.cpp: Try to maintain the number of

View File

@ -528,6 +528,7 @@ plugins += env.SharedLibrary('plugins/envmap', ['src/luminaires/envmap.cpp'])
plugins += env.SharedLibrary('plugins/spot', ['src/luminaires/spot.cpp']) plugins += env.SharedLibrary('plugins/spot', ['src/luminaires/spot.cpp'])
plugins += env.SharedLibrary('plugins/point', ['src/luminaires/point.cpp']) plugins += env.SharedLibrary('plugins/point', ['src/luminaires/point.cpp'])
plugins += env.SharedLibrary('plugins/collimated', ['src/luminaires/collimated.cpp']) plugins += env.SharedLibrary('plugins/collimated', ['src/luminaires/collimated.cpp'])
plugins += env.SharedLibrary('plugins/directional', ['src/luminaires/directional.cpp'])
# Integrators # Integrators
plugins += env.SharedLibrary('plugins/direct', ['src/integrators/direct/direct.cpp']) plugins += env.SharedLibrary('plugins/direct', ['src/integrators/direct/direct.cpp'])

View File

@ -543,6 +543,18 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) {
os << "\t\t</transform>" << endl; os << "\t\t</transform>" << endl;
os << "\t</luminaire>" << endl << endl; os << "\t</luminaire>" << endl << endl;
} }
domLight::domTechnique_common::domDirectional *directional = light.getTechnique_common()->getDirectional().cast();
if (directional) {
domFloat3 &color = directional->getColor()->getValue();
os << "\t<luminaire id=\"" << light.getId() << "\" type=\"directional\">" << endl;
os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl << endl;
os << "\t\t<transform name=\"toWorld\">" << endl;
os << "\t\t\t<lookAt ox=\"" << pos.x << "\" oy=\"" << pos.y << "\" oz=\"" << pos.z << "\" tx=\"" << target.x << "\" ty=\"" << target.y << "\" tz=\"" << target.z << "\"/>" << endl;
os << "\t\t</transform>" << endl << endl;
os << "\t</luminaire>" << endl << endl;
}
domLight::domTechnique_common::domSpot *spot = light.getTechnique_common()->getSpot().cast(); domLight::domTechnique_common::domSpot *spot = light.getTechnique_common()->getSpot().cast();
if (spot) { if (spot) {
domFloat3 &color = spot->getColor()->getValue(); domFloat3 &color = spot->getColor()->getValue();
@ -564,7 +576,7 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) {
os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl; os << "\t\t<rgb name=\"intensity\" value=\"" << color[0]*intensity << " " << color[1]*intensity << " " << color[2]*intensity << "\"/>" << endl;
os << "\t</luminaire>" << endl << endl; os << "\t</luminaire>" << endl << endl;
} }
if (!point && !spot && !ambient) if (!point && !spot && !ambient && !directional)
SLog(EWarn, "Encountered an unknown light type!"); SLog(EWarn, "Encountered an unknown light type!");
} }

View File

@ -0,0 +1,135 @@
#include <mitsuba/render/scene.h>
MTS_NAMESPACE_BEGIN
/**
* Simple directional luminaire
*/
class DirectionalLuminaire : public Luminaire {
public:
DirectionalLuminaire(const Properties &props) : Luminaire(props) {
m_radius = props.getFloat("radius", 0.01f);
m_surfaceArea = m_radius * m_radius * M_PI;
Spectrum power = props.getSpectrum("power", 1);
m_intensity = props.getSpectrum("intensity", power / m_surfaceArea);
m_invSurfaceArea = 1 / m_surfaceArea;
m_direction = m_luminaireToWorld(Vector(0, 0, 1));
m_type = EDeltaDirection | EDeltaPosition;
}
DirectionalLuminaire(Stream *stream, InstanceManager *manager)
: Luminaire(stream, manager) {
m_intensity = Spectrum(stream);
m_radius = stream->readFloat();
m_invSurfaceArea = 1 / m_surfaceArea;
m_direction = m_luminaireToWorld(Vector(0, 0, 1));
}
void serialize(Stream *stream, InstanceManager *manager) const {
Luminaire::serialize(stream, manager);
m_intensity.serialize(stream);
stream->writeFloat(m_radius);
}
Spectrum getPower() const {
return m_intensity * m_surfaceArea;
}
Spectrum Le(const LuminaireSamplingRecord &lRec) const {
/* Collimated beam is not part of the scene */
Log(EWarn, "This function should never be called.");
return Spectrum(0.0f);
}
inline Float pdf(const Point &p, const LuminaireSamplingRecord &lRec) const {
/* PDF is a delta function - zero probability when a sample point was not
generated using sample() */
return 0.0f;
}
Float pdf(const Intersection &its, const LuminaireSamplingRecord &lRec) const {
return DirectionalLuminaire::pdf(its.p, lRec);
}
inline void sample(const Point &p, LuminaireSamplingRecord &lRec,
const Point2 &sample) const {
Point local = m_worldToLuminaire(p);
Vector2 planeProjection = Vector2(local.x, local.y);
if (planeProjection.length() > m_radius || local.z < 0) {
lRec.pdf = 0.0f;
} else {
lRec.sRec.p = m_luminaireToWorld(Point(local.x, local.y, 0));
lRec.d = m_direction;
lRec.luminaire = this;
lRec.pdf = 1.0f;
lRec.Le = m_intensity;
}
}
void sample(const Intersection &its, LuminaireSamplingRecord &lRec,
const Point2 &sample) const {
DirectionalLuminaire::sample(its.p, lRec, sample);
}
void sampleEmission(EmissionRecord &eRec, const Point2 &sample1, const Point2 &sample2) const {
Point2 posOnDisk = squareToDiskConcentric(sample1) * m_radius;
eRec.sRec.p = m_luminaireToWorld(Point(posOnDisk.x, posOnDisk.y, 0));
eRec.d = m_direction;
eRec.pdfArea = m_invSurfaceArea;
eRec.pdfDir = 1;
eRec.P = m_intensity;
}
void sampleEmissionArea(EmissionRecord &eRec, const Point2 &sample) const {
Point2 posOnDisk = squareToDiskConcentric(sample) * m_radius;
eRec.sRec.p = m_luminaireToWorld(Point(posOnDisk.x, posOnDisk.y, 0));
eRec.pdfArea = m_invSurfaceArea;
eRec.P = m_intensity;
}
Spectrum sampleEmissionDirection(EmissionRecord &eRec, const Point2 &sample) const {
eRec.d = m_direction;
eRec.pdfDir = 1;
return Spectrum(1.0f);
}
Spectrum fArea(const EmissionRecord &eRec) const {
return m_intensity;
}
Spectrum f(const EmissionRecord &eRec) const {
/* Collimated beam is not part of the scene */
Log(EWarn, "This function should never be called.");
return Spectrum(0.0f);
}
void pdfEmission(EmissionRecord &eRec) const {
eRec.pdfArea = m_invSurfaceArea;
eRec.pdfDir = 0;
eRec.P = m_intensity;
}
std::string toString() const {
std::ostringstream oss;
oss << "DirectionalLuminaire[" << std::endl
<< " intensity = " << m_intensity.toString() << "," << std::endl
<< " power = " << getPower().toString() << "," << std::endl
<< " position = " << m_luminaireToWorld(Point(0, 0, 0)).toString() << "," << std::endl
<< " direction = " << m_direction.toString() << "," << std::endl
<< " radius = " << m_radius << std::endl
<< "]";
return oss.str();
}
MTS_DECLARE_CLASS()
private:
Spectrum m_intensity;
Vector m_direction;
Float m_invSurfaceArea;
Float m_radius;
};
MTS_IMPLEMENT_CLASS_S(DirectionalLuminaire, false, Luminaire)
MTS_EXPORT_PLUGIN(DirectionalLuminaire, "Directional luminaire");
MTS_NAMESPACE_END