documentation for the sphere shape

metadata
Wenzel Jakob 2011-08-22 19:41:28 -04:00
parent ae962dccac
commit 0d203940a1
13 changed files with 127 additions and 37 deletions

View File

@ -336,7 +336,7 @@
</xsd:complexType>
<xsd:complexType name="blackbody">
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="temperature" type="doubleType" use="required"/>
<xsd:attribute name="temperature" type="xsd:string" use="required"/>
<xsd:attribute name="multiplier" type="doubleType" use="optional"/>
</xsd:complexType>
</xsd:schema>

View File

@ -148,6 +148,11 @@
</xsl:copy>
</xsl:template>
<!-- Update the parameters of the sphere plugin -->
<xsl:template match="shape[@type='sphere']/boolean[@name='inverted']/@name">
<xsl:attribute name="name">flipNormals</xsl:attribute>
</xsl:template>
<!-- Update the name of the lambertian plugin -->
<xsl:template match="bsdf[@type='lambertian']/@type">
<xsl:attribute name="type">diffuse</xsl:attribute>

View File

@ -211,7 +211,7 @@ are allowed. Here is an example:
Finally, it is also possible to specify the spectral distribution of a black body emitter, where the temperature is given in Kelvin.
\begin{xml}
<blackbody name="spectrumProperty" temperature="5000"/>
<blackbody name="spectrumProperty" temperature="5000K"/>
\end{xml}
Note that attaching a black body spectrum to the \texttt{intensity} property
of a luminaire introduces physical units into the rendering process of
@ -230,7 +230,7 @@ If these units are inconsistent with your scene, you may use the
optional \texttt{multiplier} attribute:
\begin{xml}
<!-- Oops, the scene is modeled in centimeters, not meters -->
<blackbody name="spectrumProperty" temperature="5000" multiplier="0.01"/>
<blackbody name="spectrumProperty" temperature="5000K" multiplier="0.01"/>
\end{xml}
\subsubsection{Vectors, Positions}

View File

@ -57,6 +57,8 @@ def traverse(target, dirname, files):
os.chdir(os.path.dirname(__file__))
f = open('plugins_generated.tex', 'w')
f.write('\section{Plugin reference}\n')
f.write('\input{section_shapes}\n')
os.path.walk('../src/shapes', traverse, f)
f.write('\input{section_bsdf}\n')
os.path.walk('../src/bsdfs', traverse, f)
f.write('\input{section_phase}\n')

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

@ -206,10 +206,18 @@
}
@inproceedings{Jensen2001Practical,
title={A practical model for subsurface light transport},
author={Jensen, H.W. and Marschner, S.R. and Levoy, M. and Hanrahan, P.},
booktitle={Proceedings of the 28th annual conference on Computer graphics and interactive techniques},
pages={511--518},
year={2001},
organization={ACM}
title={A practical model for subsurface light transport},
author={Jensen, H.W. and Marschner, S.R. and Levoy, M. and Hanrahan, P.},
booktitle={Proceedings of the 28th annual conference on Computer graphics and interactive techniques},
pages={511--518},
year={2001},
organization={ACM}
}
@inproceedings{Shirley91Direct,
author = {Peter Shirley and Changyaw Wang},
title = {Direct Lighting Calculation by Monte Carlo Integration},
booktitle = {In proceedings of the second EUROGRAPHICS workshop on rendering},
year = {1991},
pages = {54--59},
publisher = {}
}

View File

@ -1,3 +1,4 @@
\newpage
\subsection{Surface scattering models}
\begin{figure}[h!]
\centering

View File

@ -293,8 +293,9 @@ void Scene::initialize() {
if (!m_luminairePDF.isReady()) {
if (m_luminaires.size() == 0) {
Log(EWarn, "No luminaires found -- adding a sky luminaire");
Properties skyProps("sky");
skyProps.setFloat("intensityScale", 0.1f);
Properties skyProps("sunsky");
skyProps.setFloat("skyScale", 0.1f);
skyProps.setFloat("sunScale", 0.1f);
skyProps.setBoolean("extend", true);
ref<Luminaire> luminaire = static_cast<Luminaire *>(
PluginManager::getInstance()->createObject(MTS_CLASS(Luminaire), skyProps));

View File

@ -398,11 +398,14 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
context.parent->properties.setSpectrum(context.attributes["name"],
specValue);
} else if (name == "blackbody") {
Float temperature = parseFloat(name, context.attributes["temperature"]);
std::string temperature = trim(context.attributes["temperature"]);
if (temperature.length() > 0 && std::toupper(temperature[temperature.length()-1] == 'K'))
temperature = temperature.substr(0, temperature.length()-1);
Float temperatureValue = parseFloat(name, temperature);
Float multiplier = 1;
if (context.attributes.find("multiplier") != context.attributes.end())
multiplier = parseFloat(name, context.attributes["multiplier"]);
BlackBodySpectrum bb(temperature);
BlackBodySpectrum bb(temperatureValue);
Spectrum discrete;
discrete.fromContinuousSpectrum(bb);
context.parent->properties.setSpectrum(context.attributes["name"], discrete * multiplier);

View File

@ -25,35 +25,105 @@
MTS_NAMESPACE_BEGIN
/**
* Sphere primitive.
/*!\plugin{sphere}{Sphere intersection primitive}
* \order{1}
* \parameters{
* \parameter{center}{\Point}{
* Center of the sphere in object-space \default{(0, 0, 0)}
* }
* \parameter{radius}{\Float}{
* Radius of the sphere in object-space units \default{1}
* }
* \parameter{toWorld}{\Transform}{
* Specifies an optional linear object-to-world transformation.
* Note that non-uniform scales are not permitted!
* \default{none (i.e. object space $=$ world space)}
* }
* \parameter{flipNormals}{\Boolean}{
* Is the sphere inverted, i.e. should the normal vectors
* be flipped? \default{\code{false}, i.e. the normals point outside}
* }
* }
* \renderings{
* \rendering{Basic example, see \lstref{sphere-basic}}
* {shape_sphere_basic}
* \rendering{A textured sphere with the default parameterization}
* {shape_sphere_parameterization}
* }
*
* This shape plugin describes a simple sphere intersection primitive. It should
* always be preferred over sphere approximations modeled using triangles.
*
* When using a sphere as the base object of an \pluginref{area} luminaire,
* Mitsuba will switch to a special sphere luminaire sampling strategy
* \cite{Shirley91Direct} that works much better than the default approach.
* The resulting variance reduction makes it preferable to model most light
* sources as sphere luminaires (\figref{spherelight}).
*
* \begin{xml}[caption={A sphere can either be configured using a linear
* \code{toWorld} transformation or the \code{center} and \code{radius} parameters (or both).
* The above two declarations are equivalent.}, label=lst:sphere-basic]
* <shape type="sphere">
* <transform name="toWorld">
* <scale value="2"/>
* <translate x="1" y="0" z="0"/>
* </transform>
* <bsdf type="diffuse"/>
* </shape>
*
* <shape type="sphere">
* <point name="center" x="1" y="0" z="0"/>
* <float name="radius" value="2"/>
* <bsdf type="diffuse"/>
* </shape>
* \end{xml}
*
* \renderings{
* \rendering{Spherical area light modeled using triangles}
* {shape_sphere_arealum_tri}
* \rendering{Spherical area light modeled using the \pluginref{sphere} plugin}
* {shape_sphere_arealum_analytic}
*
* \caption{
* \label{fig:spherelight}
* Area lights built from the combination of the \pluginref{area}
* and \pluginref{sphere} plugins produce renderings that have an
* overall lower variance.
* }
* }
* \begin{xml}[caption=Instantiation of a sphere luminaire]
* <shape type="sphere">
* <point name="center" x="0" y="1" z="0"/>
* <float name="radius" value="1"/>
* <luminaire type="area">
* <blackbody name="intensity" temperature="7000K"/>
* </luminaire>
* </shape>
* \end{xml}
*/
class Sphere : public Shape {
public:
Sphere(const Properties &props) : Shape(props) {
/**
* There are two ways of instantiating spheres: either,
* one can specify a linear transformation to from the
* unit sphere using the 'toWorld' parameter, or one
* can explicitly specify a radius and center.
*/
if (props.hasProperty("toWorld") && (props.hasProperty("center") || props.hasProperty("radius"))) {
Log(EError, "Deprecation error: the format for specifying spheres has changed. Please either provide "
"an object-to-world transformation (including scaling) or a radius and a center");
} else if (props.hasProperty("center") && props.hasProperty("radius")) {
m_objectToWorld =
Transform::translate(Vector(props.getPoint("center", Point(0.0f))));
m_radius = props.getFloat("radius", 1.0f);
if (props.hasProperty("toWorld")) {
Transform objectToWorld = props.getTransform("toWorld");
Float radius = objectToWorld(Vector(1,0,0)).length();
// Remove the scale from the object-to-world transform
m_objectToWorld =
Transform::translate(Vector(props.getPoint("center")));
m_radius = props.getFloat("radius");
} else {
Transform objectToWorld = props.getTransform("toWorld", Transform());
m_radius = objectToWorld(Vector(1,0,0)).length();
// Remove the scale from the object-to-world trasnsform
m_objectToWorld = objectToWorld * Transform::scale(Vector(1/m_radius));
objectToWorld
* Transform::scale(Vector(1/radius))
* m_objectToWorld;
m_radius *= radius;
}
/// Are the sphere normals pointing inwards? default: no
m_inverted = props.getBoolean("inverted", false);
m_flipNormals = props.getBoolean("flipNormals", false);
m_center = m_objectToWorld(Point(0,0,0));
m_worldToObject = m_objectToWorld.inverse();
m_invSurfaceArea = 1/(4*M_PI*m_radius*m_radius);
@ -64,7 +134,7 @@ public:
m_objectToWorld = Transform(stream);
m_radius = stream->readFloat();
m_center = Point(stream);
m_inverted = stream->readBool();
m_flipNormals = stream->readBool();
m_worldToObject = m_objectToWorld.inverse();
m_invSurfaceArea = 1/(4*M_PI*m_radius*m_radius);
}
@ -74,7 +144,7 @@ public:
m_objectToWorld.serialize(stream);
stream->writeFloat(m_radius);
m_center.serialize(stream);
stream->writeBool(m_inverted);
stream->writeBool(m_flipNormals);
}
AABB getAABB() const {
@ -163,7 +233,7 @@ public:
coordinateSystem(its.geoFrame.n, its.geoFrame.s, its.geoFrame.t);
}
if (m_inverted)
if (m_flipNormals)
its.geoFrame.n *= -1;
its.shFrame = its.geoFrame;
@ -351,7 +421,7 @@ private:
Point m_center;
Float m_radius;
Float m_invSurfaceArea;
bool m_inverted;
bool m_flipNormals;
};
MTS_IMPLEMENT_CLASS_S(Sphere, false, Shape)