diff --git a/doc/basics.tex b/doc/basics.tex
index 4f21a8c6..e7239bec 100644
--- a/doc/basics.tex
+++ b/doc/basics.tex
@@ -101,40 +101,40 @@ $\texttt{\$}$ mitsuba -c machine:1234 path-to/my-scene.xml
When no port is explicitly specified, Mitsuba uses default value of 7554.
\item \textbf{SSH}:
This approach works as follows: The renderer creates a SSH connection
- to the remote side, where it launches a Mitsuba worker instance.
- All subsequent communication then passes through the encrypted link.
- This is completely secure but slower due to the encryption overhead.
- If you are rendering a complex scene, there is a good chance that it
- won't matter much since most time is spent doing computations rather than
- communicating
+ to the remote side, where it launches a Mitsuba worker instance.
+ All subsequent communication then passes through the encrypted link.
+ This is completely secure but slower due to the encryption overhead.
+ If you are rendering a complex scene, there is a good chance that it
+ won't matter much since most time is spent doing computations rather than
+ communicating
- Such an SSH link can be created simply by using a slightly different syntax:
+ Such an SSH link can be created simply by using a slightly different syntax:
\begin{shell}
$\texttt{\$}$ mitsuba -c username@machine path-to/my-scene.xml
\end{shell}
- The above line assumes that the remote home directory contains
- a Mitsuba source directory named \code{mitsuba},
- which contains the compiled Mitsuba binaries.
- If that is not the case, you need to provide the path to such a directory manually, e.g:
+ The above line assumes that the remote home directory contains
+ a Mitsuba source directory named \code{mitsuba},
+ which contains the compiled Mitsuba binaries.
+ If that is not the case, you need to provide the path to such a directory manually, e.g:
\begin{shell}
$\texttt{\$}$ mitsuba -c username@machine:/opt/mitsuba path-to/my-scene.xml
\end{shell}
- For the SSH connection approach to work, you \emph{must} enable passwordless
- authentication.
- Try opening a terminal window and running the command \code{ssh username@machine}
- (replace with the details of your remote connection).
- If you are asked for a password, something is not set up correctly --- please see
- \url{http://www.debian-administration.org/articles/152} for instructions.
+ For the SSH connection approach to work, you \emph{must} enable passwordless
+ authentication.
+ Try opening a terminal window and running the command \code{ssh username@machine}
+ (replace with the details of your remote connection).
+ If you are asked for a password, something is not set up correctly --- please see
+ \url{http://www.debian-administration.org/articles/152} for instructions.
- On Windows, the situation is a bit more difficult since there is no suitable SSH client by
- default. To get SSH connections to work, Mitsuba requires \code{plink.exe} (from PuTTY) to
- be on the path. For passwordless authentication with a Linux/OSX-based
- server, convert your private key to PuTTY's format using \code{puttygen.exe}.
- Afterwards, start \code{pageant.exe} to load and authenticate the key. All
- of these binaries are available from the PuTTY website.
+ On Windows, the situation is a bit more difficult since there is no suitable SSH client by
+ default. To get SSH connections to work, Mitsuba requires \code{plink.exe} (from PuTTY) to
+ be on the path. For passwordless authentication with a Linux/OSX-based
+ server, convert your private key to PuTTY's format using \code{puttygen.exe}.
+ Afterwards, start \code{pageant.exe} to load and authenticate the key. All
+ of these binaries are available from the PuTTY website.
- It is possible to mix the two approaches to access some machines directly and others
- over SSH.
+ It is possible to mix the two approaches to access some machines directly and others
+ over SSH.
\end{itemize}
When doing many network-based renders over the command line, it can become tedious to
specify the connections every time. They can alternatively be loaded from a text file
@@ -155,7 +155,7 @@ For instance, you can render a scene several times with different reflectance va
on a certain material by changing its description to something like
\begin{xml}
-
+
\end{xml}
and running Mitsuba as follows:
diff --git a/doc/compiling.tex b/doc/compiling.tex
index aad60be2..f9d51407 100644
--- a/doc/compiling.tex
+++ b/doc/compiling.tex
@@ -322,10 +322,10 @@ configuration file from the \texttt{build} directory.
\subsection{Building on Mac OS X}
\vspace{-5mm}
\remarks{
- \item Unfortunately, OpenMP is not available when compiling
- using the regular \code{clang} toolchain (it is available when using Intel XE Composer). This will cause the following parts of Mitsuba
- to run single-threaded: bitmap resampling (i.e. MIP map generation), blue noise point generation in the \pluginref{dipole}
- plugin, as well as the \pluginref{ppm} and \pluginref{sppm} plugins.
+ \item Unfortunately, OpenMP is not available when compiling
+ using the regular \code{clang} toolchain (it is available when using Intel XE Composer). This will cause the following parts of Mitsuba
+ to run single-threaded: bitmap resampling (i.e. MIP map generation), blue noise point generation in the \pluginref{dipole}
+ plugin, as well as the \pluginref{ppm} and \pluginref{sppm} plugins.
}
Compiling Mitsuba's dependencies on Mac OS is a laborious process; for convenience, there
is a repository that provides them in precompiled form. To use this repository, clone it
diff --git a/doc/development.tex b/doc/development.tex
index aae78c42..523197c9 100644
--- a/doc/development.tex
+++ b/doc/development.tex
@@ -10,15 +10,15 @@ to become part of the main codebase.
Mitsuba is split into four basic support libraries:
\begin{itemize}
\item The core library (\code{libcore}) implements basic functionality such as
- cross-platform file and bitmap I/O, data structures, scheduling, as well as logging and plugin management.
+ cross-platform file and bitmap I/O, data structures, scheduling, as well as logging and plugin management.
\item The rendering library (\code{librender}) contains abstractions
- needed to load and represent scenes containing light sources, shapes, materials, and participating media.
+ needed to load and represent scenes containing light sources, shapes, materials, and participating media.
\item The hardware acceleration library (\code{libhw})
- implements a cross-platform display library, an object-oriented OpenGL
- wrapper, as well as support for rendering interactive previews of scenes.
+ implements a cross-platform display library, an object-oriented OpenGL
+ wrapper, as well as support for rendering interactive previews of scenes.
\item Finally, the bidirectional library (\code{libbidir})
- contains a support layer that is used to implement bidirectional rendering algorithms such as
- Bidirectional Path Tracing and Metropolis Light Transport.
+ contains a support layer that is used to implement bidirectional rendering algorithms such as
+ Bidirectional Path Tracing and Metropolis Light Transport.
\end{itemize}
A detailed reference of these APIs is available at
\url{http://www.mitsuba-renderer.org/api}. The next sections
@@ -33,18 +33,18 @@ this way, otherwise the source code layout will look garbled.
same line to make the best use of vertical space, i.e.
\begin{cpp}
if (x > y) {
- x = y;
+ x = y;
}
\end{cpp}
\paragraph{Placement of spaces:} Placement of spaces follows K\&R, e.g.
\begin{cpp}
if (x == y) {
- ..
+ ..
} else if (x > y) {
- ..
+ ..
} else {
- ..
+ ..
}
\end{cpp}
rather than things like this
@@ -61,12 +61,12 @@ have the prefix \code{m\_}. Here is an example:
\begin{cpp}
class MyClass {
public:
- MyClass(int value) : m_value(value) { }
+ MyClass(int value) : m_value(value) { }
- inline void setValue(int value) { m_value = value; }
- inline int getValue() const { return m_value; }
+ inline void setValue(int value) { m_value = value; }
+ inline int getValue() const { return m_value; }
private:
- int m_value;
+ int m_value;
};
\end{cpp}
@@ -74,9 +74,9 @@ private:
start with a capital \textbf{E}, e.g.
\begin{cpp}
enum ETristate {
- ENo = 0,
- EYes,
- EMaybe
+ ENo = 0,
+ EYes,
+ EMaybe
};
\end{cpp}
\paragraph{Constant methods and parameters:} Declare member functions and
@@ -102,8 +102,8 @@ counting. This is done using the \code{ref<>} template, e.g.
\begin{cpp}
if (..) {
- ref instance = new MyClass();
- instance->doSomething()
+ ref instance = new MyClass();
+ instance->doSomething()
} // reference expires, instance will be deallocated
\end{cpp}
diff --git a/doc/format.tex b/doc/format.tex
index 0e5bb0ea..e234b94c 100644
--- a/doc/format.tex
+++ b/doc/format.tex
@@ -12,9 +12,9 @@ something like this:
\begin{xml}
-
-
-
+
+
+
\end{xml}
The scene version attribute denotes the release of Mitsuba that was used to
@@ -35,9 +35,9 @@ Similarly, you could write
\begin{xml}
-
-
-
+
+
+
\end{xml}
This loads a different plugin (\code{sphere}) which is still a \emph{Shape}, but instead represents
@@ -51,55 +51,55 @@ and one or more emitters. Here is a more complex example:
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
\end{xml}
This example introduces several new object types (\code{integrator, sensor, bsdf, sampler, film}, and \code{emitter})
@@ -211,10 +211,10 @@ are allowed. Here is an example:
\end{xml}
\renderings{
- \fbox{\includegraphics[width=10cm]{images/blackbody}}
- \hfill\,
- \caption{\label{fig:blackbody}A few simulated
- black body emitters over a range of temperature values}
+ \fbox{\includegraphics[width=10cm]{images/blackbody}}
+ \hfill\,
+ \caption{\label{fig:blackbody}A few simulated
+ black body emitters over a range of temperature values}
}
\label{sec:blackbody}
Finally, it is also possible to specify the spectral distribution of a black body emitter (\figref{blackbody}),
@@ -252,8 +252,8 @@ with the identity, one can build up a transformation using a sequence of command
does a translation followed by a rotation might be written like this:
\begin{xml}
-
-
+
+
\end{xml}
Mathematically, each incremental transformation in the sequence is left-multiplied onto the current one. The following
@@ -323,22 +323,22 @@ to declare it over and over again, which wastes memory, you can make use of refe
of how this works:
\begin{xml}
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
+
\end{xml}
By providing a unique \texttt{id} attribute in the
diff --git a/doc/integrator.tex b/doc/integrator.tex
index e4501830..b2742dfc 100644
--- a/doc/integrator.tex
+++ b/doc/integrator.tex
@@ -40,7 +40,7 @@ MTS_NAMESPACE_BEGIN
class MyIntegrator : public SamplingIntegrator {
public:
- MTS_DECLARE_CLASS()
+ MTS_DECLARE_CLASS()
};
MTS_IMPLEMENT_CLASS_S(MyIntegrator, false, SamplingIntegrator)
@@ -87,7 +87,7 @@ public:
}
private:
- Spectrum m_color;
+ Spectrum m_color;
\end{cpp}
This code fragment sets up a default color (a light shade of green), which
@@ -96,7 +96,7 @@ the integrator from an XML document like this
\begin{xml}
-
+
\end{xml}
in which case white would take preference.
@@ -189,11 +189,11 @@ substituted based the compilation flags. This variable constitutes local
state, thus it must not be forgotten in the serialization- and unserialization routines:
append
\begin{cpp}
- m_maxDist = stream->readFloat();
+ m_maxDist = stream->readFloat();
\end{cpp}
and
\begin{cpp}
- stream->writeFloat(m_maxDist);
+ stream->writeFloat(m_maxDist);
\end{cpp}
to the unserialization constructor and the \code{serialize} method, respectively.
@@ -202,24 +202,24 @@ distance to all corners of the bounding box, which encloses the scene.
To avoid having to do this every time \code{Li()} is called,
we can override the \code{preprocess} function:
\begin{cpp}
- /// Preprocess function -- called on the initiating machine
- bool preprocess(const Scene *scene, RenderQueue *queue,
- const RenderJob *job, int sceneResID, int cameraResID,
- int samplerResID) {
- SamplingIntegrator::preprocess(scene, queue, job, sceneResID,
- cameraResID, samplerResID);
+ /// Preprocess function -- called on the initiating machine
+ bool preprocess(const Scene *scene, RenderQueue *queue,
+ const RenderJob *job, int sceneResID, int cameraResID,
+ int samplerResID) {
+ SamplingIntegrator::preprocess(scene, queue, job, sceneResID,
+ cameraResID, samplerResID);
- const AABB &sceneAABB = scene->getAABB();
+ const AABB &sceneAABB = scene->getAABB();
/* Find the camera position at t=0 seconds */
- Point cameraPosition = scene->getSensor()->getWorldTransform()->eval(0).transformAffine(Point(0.0f));
- m_maxDist = - std::numeric_limits::infinity();
+ Point cameraPosition = scene->getSensor()->getWorldTransform()->eval(0).transformAffine(Point(0.0f));
+ m_maxDist = - std::numeric_limits::infinity();
- for (int i=0; i<8; ++i)
- m_maxDist = std::max(m_maxDist,
- (cameraPosition - sceneAABB.getCorner(i)).length());
+ for (int i=0; i<8; ++i)
+ m_maxDist = std::max(m_maxDist,
+ (cameraPosition - sceneAABB.getCorner(i)).length());
- return true;
- }
+ return true;
+ }
\end{cpp}
The bottom of this function should be relatively self-explanatory. The
numerous arguments at the top are related to the parallelization layer, which will be
@@ -238,11 +238,11 @@ other nodes before the rendering begins.
Now, replace the body of the \code{Li} method with
\begin{cpp}
- if (rRec.rayIntersect(r)) {
- Float distance = rRec.its.t;
- return Spectrum(1.0f - distance/m_maxDist) * m_color;
- }
- return Spectrum(0.0f);
+ if (rRec.rayIntersect(r)) {
+ Float distance = rRec.its.t;
+ return Spectrum(1.0f - distance/m_maxDist) * m_color;
+ }
+ return Spectrum(0.0f);
\end{cpp}
and the distance renderer is done!
\begin{center}
@@ -251,11 +251,11 @@ and the distance renderer is done!
There are a few more noteworthy details: first of all, the ``usual'' way
to intersect a ray against the scene actually works like this:
\begin{cpp}
- Intersection its;
- Ray ray = ...;
- if (scene->rayIntersect(ray, its)) {
- /* Do something with the intersection stored in 'its' */
- }
+ Intersection its;
+ Ray ray = ...;
+ if (scene->rayIntersect(ray, its)) {
+ /* Do something with the intersection stored in 'its' */
+ }
\end{cpp}
As you can see, we did something slightly different in the distance
renderer fragment above (we called \code{RadianceQueryRecord::rayIntersect()}
@@ -269,11 +269,11 @@ into a scene XML file:
\begin{xml}
-
-
-
-
-
+
+
+
+
+
\end{xml}
To support this kind of complex interaction, some information needs to be passed between the
@@ -294,16 +294,16 @@ as possible. Your overall code might for example be structured like this:
\begin{cpp}
Spectrum Li(const RayDifferential &r, RadianceQueryRecord &rRec) const {
- Spectrum result;
+ Spectrum result;
if (rRec.type & RadianceQueryRecord::EEmittedRadiance) {
// Emitted surface radiance contribution was requested
- result += ...;
- }
+ result += ...;
+ }
if (rRec.type & RadianceQueryRecord::EDirectRadiance) {
// Direct illumination contribution was requested
- result += ...;
- }
- ...
- return result;
+ result += ...;
+ }
+ ...
+ return result;
}
\end{cpp}
diff --git a/doc/introduction.tex b/doc/introduction.tex
index 298faf08..f57c8018 100644
--- a/doc/introduction.tex
+++ b/doc/introduction.tex
@@ -91,8 +91,8 @@ Mitsuba is free software and can be redistributed and modified under the terms o
Public License (Version 3) as provided by the Free Software Foundation.
\remarks{
- \item Being a ``viral'' license, the GPL automatically applies to all
- derivative work. Amongst other things, this means that without express
- permission, Mitsuba's source code is \emph{off-limits} to companies that
- develop rendering software not distributed under a compatible license.
+ \item Being a ``viral'' license, the GPL automatically applies to all
+ derivative work. Amongst other things, this means that without express
+ permission, Mitsuba's source code is \emph{off-limits} to companies that
+ develop rendering software not distributed under a compatible license.
}
diff --git a/doc/main.tex b/doc/main.tex
index 3bb1e21a..35846468 100644
--- a/doc/main.tex
+++ b/doc/main.tex
@@ -61,19 +61,19 @@
\pagestyle{scrheadings}
\usepackage[
- bookmarks,
- bookmarksnumbered,
- colorlinks,
- plainpages=false,
- pdfpagelabels,
- hypertexnames=false,
- linkcolor=myblue,
- urlcolor=myblue,
- citecolor=myblue,
- pdfpagelabels,
- pdftitle={Mitsuba \MitsubaVersion\, Documentation},
- pdfauthor={Wenzel Jakob},
- pdfstartview=FitH
+ bookmarks,
+ bookmarksnumbered,
+ colorlinks,
+ plainpages=false,
+ pdfpagelabels,
+ hypertexnames=false,
+ linkcolor=myblue,
+ urlcolor=myblue,
+ citecolor=myblue,
+ pdfpagelabels,
+ pdftitle={Mitsuba \MitsubaVersion\, Documentation},
+ pdfauthor={Wenzel Jakob},
+ pdfstartview=FitH
]{hyperref}
\definecolor{myblue}{rgb}{0,.1,.6}
@@ -85,40 +85,47 @@
\definecolor{remark}{rgb}{1.0, 0.9, 0.9}
\definecolor{remarkframe}{rgb}{1.0, 0.7, 0.7}
+% requires the latest version of package accsupp
+\usepackage[space=true]{accsupp}
+\newcommand{\copyablespace}{\BeginAccSupp{method=hex,unicode,ActualText=00A0}\ \EndAccSupp{}}
+
% Listings settings
\lstset{
- basicstyle = \small\ttfamily\raggedright,
- commentstyle=\color{lstcomment}\itshape,
- stringstyle=\color{lstattrib},
- mathescape = true,
- frame = lrtb,
- backgroundcolor = \color{lstshade},
- rulecolor = \color{lstframe},
- tabsize = 4,
- columns = flexible,
- keepspaces,
- belowskip = \smallskipamount,
- framerule = .7pt,
- breaklines = true,
- showstringspaces = false,
- keywordstyle = \bfseries,
- captionpos = b,
- upquote = true
+ basicstyle = \small\ttfamily\raggedright,
+ commentstyle=\color{lstcomment}\itshape,
+ stringstyle=\color{lstattrib},
+ mathescape = true,
+ frame = lrtb,
+ backgroundcolor = \color{lstshade},
+ rulecolor = \color{lstframe},
+ tabsize = 4,
+ columns = fullflexible,
+ keepspaces,
+ belowskip = \smallskipamount,
+ framerule = .7pt,
+ breaklines = true,
+ showstringspaces = false,
+ keywordstyle = \bfseries,
+ captionpos = b,
+ upquote = true,
+ literate={*}{{\char42}}1
+ {-}{{\char45}}1
+ {\ }{{\copyablespace}}1
}
\lstdefinelanguage{xml} {
- sensitive=true,
- morecomment=[s][\color{lstcomment}\itshape]{},
- morecomment=[s][\color{lstcomment}]{}{?>},
- string=[b]", stringstyle=\color{lstattrib},
- keywords= [1] {
- shape,bsdf,scene,texture,phase,integer,float,
- string,transform,ref,rgb,srgb,spectrum,blackbody,
- medium,film,sampler,integrator,emitter,sensor,
- translate,rotate,scale,lookat,point,vector,matrix,
- include,fscat,volume,alias,rfilter,boolean,
- subsurface,animation
- },
+ sensitive=true,
+ morecomment=[s][\color{lstcomment}\itshape]{},
+ morecomment=[s][\color{lstcomment}]{}{?>},
+ string=[b]", stringstyle=\color{lstattrib},
+ keywords= [1] {
+ shape,bsdf,scene,texture,phase,integer,float,
+ string,transform,ref,rgb,srgb,spectrum,blackbody,
+ medium,film,sampler,integrator,emitter,sensor,
+ translate,rotate,scale,lookat,point,vector,matrix,
+ include,fscat,volume,alias,rfilter,boolean,
+ subsurface,animation
+ },
}
@@ -133,25 +140,25 @@
\setlength{\intextsep}{3pt}
\lstnewenvironment{shell}[1][]{\lstset{#1}}
- {}
+ {}
\lstnewenvironment{cpp}[1][]{\lstset{language=c++, #1}}
- {}
+ {}
\lstnewenvironment{python}[1][]{\lstset{language=Python, #1}}
- {}
+ {}
\lstnewenvironment{xml}[1][]{\lstset{language=xml, #1}}
- {}
+ {}
\lstnewenvironment{console}[1][]{\lstset{basicstyle=\footnotesize\ttfamily, float, #1}}
- {}
+ {}
% ----- 8< ----- 8< ------
\title{
- \vspace{3cm}
- \includegraphics[width=4cm]{images/logo_plain.pdf}\\\vspace{1.5cm}
- \Huge
- Mitsuba Documentation\\\vspace{4mm}
- \LARGE Version \MitsubaVersion
- \vspace{5mm}
+ \vspace{3cm}
+ \includegraphics[width=4cm]{images/logo_plain.pdf}\\\vspace{1.5cm}
+ \Huge
+ Mitsuba Documentation\\\vspace{4mm}
+ \LARGE Version \MitsubaVersion
+ \vspace{5mm}
}
\author{Wenzel Jakob}
\date{\today}
diff --git a/doc/parallelization.tex b/doc/parallelization.tex
index 224e3dfb..640d5d86 100644
--- a/doc/parallelization.tex
+++ b/doc/parallelization.tex
@@ -36,12 +36,12 @@ MTS_NAMESPACE_BEGIN
class ROT13Encoder : public Utility {
public:
- int run(int argc, char **argv) {
- cout << "Hello world!" << endl;
- return 0;
- }
+ int run(int argc, char **argv) {
+ cout << "Hello world!" << endl;
+ return 0;
+ }
- MTS_DECLARE_UTILITY()
+ MTS_DECLARE_UTILITY()
};
MTS_EXPORT_UTILITY(ROT13Encoder, "Perform a ROT13 encryption of a string")
@@ -58,8 +58,8 @@ $\texttt{\$}$ mtsutil
..
The following utilities are available:
- addimages Generate linear combinations of EXR images
- rot13 Perform a ROT13 encryption of a string
+ addimages Generate linear combinations of EXR images
+ rot13 Perform a ROT13 encryption of a string
\end{shell}
It can be executed as follows:
\begin{shell}
@@ -82,22 +82,22 @@ For reference, here are the interfaces of \code{WorkUnit} and \code{WorkResult}:
*/
class MTS_EXPORT_CORE WorkUnit : public Object {
public:
- /// Copy the content of another work unit of the same type
- virtual void set(const WorkUnit *workUnit) = 0;
+ /// Copy the content of another work unit of the same type
+ virtual void set(const WorkUnit *workUnit) = 0;
- /// Fill the work unit with content acquired from a binary data stream
- virtual void load(Stream *stream) = 0;
+ /// Fill the work unit with content acquired from a binary data stream
+ virtual void load(Stream *stream) = 0;
- /// Serialize a work unit to a binary data stream
- virtual void save(Stream *stream) const = 0;
+ /// Serialize a work unit to a binary data stream
+ virtual void save(Stream *stream) const = 0;
- /// Return a string representation
- virtual std::string toString() const = 0;
+ /// Return a string representation
+ virtual std::string toString() const = 0;
- MTS_DECLARE_CLASS()
+ MTS_DECLARE_CLASS()
protected:
- /// Virtual destructor
- virtual ~WorkUnit() { }
+ /// Virtual destructor
+ virtual ~WorkUnit() { }
};
/**
* Abstract work result. Represents the information that encodes
@@ -105,60 +105,60 @@ protected:
*/
class MTS_EXPORT_CORE WorkResult : public Object {
public:
- /// Fill the work result with content acquired from a binary data stream
- virtual void load(Stream *stream) = 0;
+ /// Fill the work result with content acquired from a binary data stream
+ virtual void load(Stream *stream) = 0;
- /// Serialize a work result to a binary data stream
- virtual void save(Stream *stream) const = 0;
+ /// Serialize a work result to a binary data stream
+ virtual void save(Stream *stream) const = 0;
- /// Return a string representation
- virtual std::string toString() const = 0;
+ /// Return a string representation
+ virtual std::string toString() const = 0;
- MTS_DECLARE_CLASS()
+ MTS_DECLARE_CLASS()
protected:
- /// Virtual destructor
- virtual ~WorkResult() { }
+ /// Virtual destructor
+ virtual ~WorkResult() { }
};
\end{cpp}
In our case, the \code{WorkUnit} implementation then looks like this:
\begin{cpp}
class ROT13WorkUnit : public WorkUnit {
public:
- void set(const WorkUnit *workUnit) {
- const ROT13WorkUnit *wu =
- static_cast(workUnit);
- m_char = wu->m_char;
- m_pos = wu->m_pos;
- }
+ void set(const WorkUnit *workUnit) {
+ const ROT13WorkUnit *wu =
+ static_cast(workUnit);
+ m_char = wu->m_char;
+ m_pos = wu->m_pos;
+ }
- void load(Stream *stream) {
- m_char = stream->readChar();
- m_pos = stream->readInt();
- }
+ void load(Stream *stream) {
+ m_char = stream->readChar();
+ m_pos = stream->readInt();
+ }
- void save(Stream *stream) const {
- stream->writeChar(m_char);
- stream->writeInt(m_pos);
- }
+ void save(Stream *stream) const {
+ stream->writeChar(m_char);
+ stream->writeInt(m_pos);
+ }
- std::string toString() const {
- std::ostringstream oss;
- oss << "ROT13WorkUnit[" << endl
- << " char = '" << m_char << "'," << endl
- << " pos = " << m_pos << endl
- << "]";
- return oss.str();
- }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << "ROT13WorkUnit[" << endl
+ << " char = '" << m_char << "'," << endl
+ << " pos = " << m_pos << endl
+ << "]";
+ return oss.str();
+ }
- inline char getChar() const { return m_char; }
- inline void setChar(char value) { m_char = value; }
- inline int getPos() const { return m_pos; }
- inline void setPos(int value) { m_pos = value; }
+ inline char getChar() const { return m_char; }
+ inline void setChar(char value) { m_char = value; }
+ inline int getPos() const { return m_pos; }
+ inline void setPos(int value) { m_pos = value; }
- MTS_DECLARE_CLASS()
+ MTS_DECLARE_CLASS()
private:
- char m_char;
- int m_pos;
+ char m_char;
+ int m_pos;
};
MTS_IMPLEMENT_CLASS(ROT13WorkUnit, false, WorkUnit)
@@ -175,42 +175,42 @@ remote worker nodes and replicated amongst local threads.
\begin{cpp}
class ROT13WorkProcessor : public WorkProcessor {
public:
- /// Construct a new work processor
- ROT13WorkProcessor() : WorkProcessor() { }
+ /// Construct a new work processor
+ ROT13WorkProcessor() : WorkProcessor() { }
- /// Unserialize from a binary data stream (nothing to do in our case)
- ROT13WorkProcessor(Stream *stream, InstanceManager *manager)
- : WorkProcessor(stream, manager) { }
+ /// Unserialize from a binary data stream (nothing to do in our case)
+ ROT13WorkProcessor(Stream *stream, InstanceManager *manager)
+ : WorkProcessor(stream, manager) { }
- /// Serialize to a binary data stream (nothing to do in our case)
- void serialize(Stream *stream, InstanceManager *manager) const {
- }
+ /// Serialize to a binary data stream (nothing to do in our case)
+ void serialize(Stream *stream, InstanceManager *manager) const {
+ }
- ref createWorkUnit() const {
- return new ROT13WorkUnit();
- }
+ ref createWorkUnit() const {
+ return new ROT13WorkUnit();
+ }
- ref createWorkResult() const {
- return new ROT13WorkResult();
- }
+ ref createWorkResult() const {
+ return new ROT13WorkResult();
+ }
- ref clone() const {
- return new ROT13WorkProcessor(); // No state to clone in our case
- }
+ ref clone() const {
+ return new ROT13WorkProcessor(); // No state to clone in our case
+ }
- /// No internal state, thus no preparation is necessary
- void prepare() { }
+ /// No internal state, thus no preparation is necessary
+ void prepare() { }
- /// Do the actual computation
- void process(const WorkUnit *workUnit, WorkResult *workResult,
- const bool &stop) {
- const ROT13WorkUnit *wu
- = static_cast(workUnit);
- ROT13WorkResult *wr = static_cast(workResult);
- wr->setPos(wu->getPos());
- wr->setChar((std::toupper(wu->getChar()) - 'A' + 13) % 26 + 'A');
- }
- MTS_DECLARE_CLASS()
+ /// Do the actual computation
+ void process(const WorkUnit *workUnit, WorkResult *workResult,
+ const bool &stop) {
+ const ROT13WorkUnit *wu
+ = static_cast(workUnit);
+ ROT13WorkResult *wr = static_cast(workResult);
+ wr->setPos(wu->getPos());
+ wr->setChar((std::toupper(wu->getChar()) - 'A' + 13) % 26 + 'A');
+ }
+ MTS_DECLARE_CLASS()
};
MTS_IMPLEMENT_CLASS_S(ROT13WorkProcessor, false, WorkProcessor)
\end{cpp}
@@ -226,48 +226,48 @@ implementation might look as follows:
\begin{cpp}
class ROT13Process : public ParallelProcess {
public:
- ROT13Process(const std::string &input) : m_input(input), m_pos(0) {
- m_output.resize(m_input.length());
- }
+ ROT13Process(const std::string &input) : m_input(input), m_pos(0) {
+ m_output.resize(m_input.length());
+ }
- ref createWorkProcessor() const {
- return new ROT13WorkProcessor();
- }
+ ref createWorkProcessor() const {
+ return new ROT13WorkProcessor();
+ }
- std::vector getRequiredPlugins() {
- std::vector result;
- result.push_back("rot13");
- return result;
- }
+ std::vector getRequiredPlugins() {
+ std::vector result;
+ result.push_back("rot13");
+ return result;
+ }
- EStatus generateWork(WorkUnit *unit, int worker /* unused */) {
- if (m_pos >= (int) m_input.length())
- return EFailure;
- ROT13WorkUnit *wu = static_cast(unit);
+ EStatus generateWork(WorkUnit *unit, int worker /* unused */) {
+ if (m_pos >= (int) m_input.length())
+ return EFailure;
+ ROT13WorkUnit *wu = static_cast(unit);
- wu->setPos(m_pos);
- wu->setChar(m_input[m_pos++]);
+ wu->setPos(m_pos);
+ wu->setChar(m_input[m_pos++]);
- return ESuccess;
- }
+ return ESuccess;
+ }
- void processResult(const WorkResult *result, bool cancelled) {
- if (cancelled) // indicates a work unit, which was
- return; // cancelled partly through its execution
- const ROT13WorkResult *wr =
- static_cast(result);
- m_output[wr->getPos()] = wr->getChar();
- }
+ void processResult(const WorkResult *result, bool cancelled) {
+ if (cancelled) // indicates a work unit, which was
+ return; // cancelled partly through its execution
+ const ROT13WorkResult *wr =
+ static_cast(result);
+ m_output[wr->getPos()] = wr->getChar();
+ }
- inline const std::string &getOutput() {
- return m_output;
- }
+ inline const std::string &getOutput() {
+ return m_output;
+ }
- MTS_DECLARE_CLASS()
+ MTS_DECLARE_CLASS()
public:
- std::string m_input;
- std::string m_output;
- int m_pos;
+ std::string m_input;
+ std::string m_output;
+ int m_pos;
};
MTS_IMPLEMENT_CLASS(ROT13Process, false, ParallelProcess)
\end{cpp}
@@ -281,25 +281,25 @@ loads the \code{ROT13*} classes at the right moment.
To actually use the \code{ROT13} encoder, we must first launch the newly created parallel process
from the main utility function (the `Hello World' code we wrote earlier). We can adapt it as follows:
\begin{cpp}
- int run(int argc, char **argv) {
- if (argc < 2) {
- cout << "Syntax: mtsutil rot13 " << endl;
- return -1;
- }
+ int run(int argc, char **argv) {
+ if (argc < 2) {
+ cout << "Syntax: mtsutil rot13 " << endl;
+ return -1;
+ }
- ref proc = new ROT13Process(argv[1]);
- ref sched = Scheduler::getInstance();
+ ref proc = new ROT13Process(argv[1]);
+ ref sched = Scheduler::getInstance();
- /* Submit the encryption job to the scheduler */
- sched->schedule(proc);
+ /* Submit the encryption job to the scheduler */
+ sched->schedule(proc);
- /* Wait for its completion */
- sched->wait(proc);
+ /* Wait for its completion */
+ sched->wait(proc);
- cout << "Result: " << proc->getOutput() << endl;
+ cout << "Result: " << proc->getOutput() << endl;
- return 0;
- }
+ return 0;
+ }
\end{cpp}
After compiling everything using \code{scons}, a simple example
involving the utility would be to encode a string (e.g. \code{SECUREBYDESIGN}), while
diff --git a/doc/plugins.tex b/doc/plugins.tex
index 91824168..58a13713 100644
--- a/doc/plugins.tex
+++ b/doc/plugins.tex
@@ -10,21 +10,21 @@ The documentation of a plugin always starts on a new page and is preceded
by a table similar to the one below:
\parameters{
\parameter{softRays}{\Boolean}{
- Try not to damage objects in the scene by shooting softer rays
- \default{\code{false}}
- }
+ Try not to damage objects in the scene by shooting softer rays
+ \default{\code{false}}
+ }
\parameter{darkMatter}{\Float}{
- Controls the proportionate amount of dark matter present in the scene.
- \default{0.83}
- }
+ Controls the proportionate amount of dark matter present in the scene.
+ \default{0.83}
+ }
}
Suppose this hypothetical plugin is an \emph{integrator} named \code{amazing}. Then, based on
this description, it can be instantiated from an XML scene file using a custom configuration such as:
\begin{xml}
-
-
+
+
\end{xml}
In some cases\footnote{Note that obvious parameters are generally omitted.
@@ -33,20 +33,20 @@ is left out from the documentation for brevity.}, plugins also indicate that the
as input arguments. These can either be \emph{named} or \emph{unnamed}. If
the \code{amazing} integrator also accepted the following two parameters\vspace{-2mm}
\parameters{
- \parameter{\Unnamed}{\Integrator}{A nested integrator which does the actual hard work}
- \parameter{puppies}{\Texture}{This must be used to supply a \mbox{cute picture of puppies}}
+ \parameter{\Unnamed}{\Integrator}{A nested integrator which does the actual hard work}
+ \parameter{puppies}{\Texture}{This must be used to supply a \mbox{cute picture of puppies}}
}
\vspace{-1mm}
then it can be instantiated e.g. as follows
\begin{xml}
-
-
-
-
-
-
+
+
+
+
+
+
\end{xml}
or, if these were already instantiated previously and are now
@@ -54,10 +54,10 @@ bound to the \emph{identifiers} (\secref{format}) \code{myPathTracer} and
\code{myTexture}, the following also works:
\begin{xml}
-
-
-
-
+
+
+
+
\end{xml}
diff --git a/doc/python.tex b/doc/python.tex
index 8ba43f87..d5bb47e3 100644
--- a/doc/python.tex
+++ b/doc/python.tex
@@ -153,7 +153,7 @@ scheduler = Scheduler.getInstance()
# Start up the scheduling system with one worker per local core
for i in range(0, multiprocessing.cpu_count()):
- scheduler.registerWorker(LocalWorker(i, 'wrk%i' % i))
+ scheduler.registerWorker(LocalWorker(i, 'wrk%i' % i))
scheduler.start()
# Create a queue for tracking render jobs
@@ -204,9 +204,9 @@ pmgr = PluginManager.getInstance()
# Encodes parameters on how to instantiate the 'perspective' plugin
sensorProps = Properties('perspective')
sensorProps['toWorld'] = Transform.lookAt(
- Point(0, 0, -10), # Camera origin
- Point(0, 0, 0), # Camera target
- Vector(0, 1, 0) # 'up' vector
+ Point(0, 0, -10), # Camera origin
+ Point(0, 0, 0), # Camera target
+ Vector(0, 1, 0) # 'up' vector
)
sensorProps['fov'] = 45.0
@@ -243,17 +243,17 @@ from mitsuba.core import *
pmgr = PluginManager.getInstance()
sensor = pmgr.create({
- 'type' : 'perspective',
- 'toWorld' : Transform.lookAt(
- Point(0, 0, -10),
- Point(0, 0, 0),
- Vector(0, 1, 0)
- ),
- 'film' : {
- 'type' : 'ldrfilm',
- 'width' : 1920,
- 'height' : 1080
- }
+ 'type' : 'perspective',
+ 'toWorld' : Transform.lookAt(
+ Point(0, 0, -10),
+ Point(0, 0, 0),
+ Vector(0, 1, 0)
+ ),
+ 'film' : {
+ 'type' : 'ldrfilm',
+ 'width' : 1920,
+ 'height' : 1080
+ }
})
\end{python}
This code does exactly the same as the previous snippet.
@@ -273,44 +273,44 @@ scene = Scene()
# Create a sensor, film & sample generator
scene.addChild(pmgr.create({
- 'type' : 'perspective',
- 'toWorld' : Transform.lookAt(
- Point(0, 0, -10),
- Point(0, 0, 0),
- Vector(0, 1, 0)
- ),
- 'film' : {
- 'type' : 'ldrfilm',
- 'width' : 1920,
- 'height' : 1080
- },
- 'sampler' : {
- 'type' : 'ldsampler',
- 'sampleCount' : 2
- }
+ 'type' : 'perspective',
+ 'toWorld' : Transform.lookAt(
+ Point(0, 0, -10),
+ Point(0, 0, 0),
+ Vector(0, 1, 0)
+ ),
+ 'film' : {
+ 'type' : 'ldrfilm',
+ 'width' : 1920,
+ 'height' : 1080
+ },
+ 'sampler' : {
+ 'type' : 'ldsampler',
+ 'sampleCount' : 2
+ }
}))
# Set the integrator
scene.addChild(pmgr.create({
- 'type' : 'direct'
+ 'type' : 'direct'
}))
# Add a light source
scene.addChild(pmgr.create({
- 'type' : 'point',
- 'position' : Point(5, 0, -10),
- 'intensity' : Spectrum(100)
+ 'type' : 'point',
+ 'position' : Point(5, 0, -10),
+ 'intensity' : Spectrum(100)
}))
# Add a shape
scene.addChild(pmgr.create({
- 'type' : 'sphere',
- 'center' : Point(0, 0, 0),
- 'radius' : 1.0,
- 'bsdf' : {
- 'type' : 'diffuse',
- 'reflectance' : Spectrum(0.4)
- }
+ 'type' : 'sphere',
+ 'center' : Point(0, 0, 0),
+ 'radius' : 1.0,
+ 'bsdf' : {
+ 'type' : 'diffuse',
+ 'reflectance' : Spectrum(0.4)
+ }
}))
scene.configure()
@@ -334,17 +334,17 @@ import mitsuba
from mitsuba.core import *
class MyFormatter(Formatter):
- def format(self, logLevel, sourceClass, sourceThread, message, filename, line):
- return '%s (log level: %s, thread: %s, class %s, file %s, line %i)' % \
- (message, str(logLevel), sourceThread.getName(), sourceClass,
- filename, line)
+ def format(self, logLevel, sourceClass, sourceThread, message, filename, line):
+ return '%s (log level: %s, thread: %s, class %s, file %s, line %i)' % \
+ (message, str(logLevel), sourceThread.getName(), sourceClass,
+ filename, line)
class MyAppender(Appender):
- def append(self, logLevel, message):
- print(message)
+ def append(self, logLevel, message):
+ print(message)
- def logProgress(self, progress, name, formatted, eta):
- print('Progress message: ' + formatted)
+ def logProgress(self, progress, name, formatted, eta):
+ print('Progress message: ' + formatted)
# Get the logger associated with the current thread
logger = Thread.getThread().getLogger()
@@ -810,3 +810,32 @@ Suppose that \code{bitmap} contains a \code{mitsuba.core.Bitmap} instance (e.g.
import numpy as np
array = np.array(bitmap.getNativeBuffer())
\end{python}
+
+\subsubsection{Simultaneously rendering multiple versions of a scene}
+\begin{python}
+for i in range(2):
+ destination = 'renderedResult' + str(i)
+
+ # Create a shallow copy of the scene so that the queue can tell apart the two
+ # rendering processes. This takes almost no extra memory
+ newScene = Scene(scene)
+
+ newSensor = PluginManager.getInstance().createObject(scene.getSensor().getProperties())
+ newFilm = PluginManager.getInstance().createObject(scene.getFilm().getProperties())
+ newFilm.configure()
+ newSensor.addChild(newFilm)
+ newSensor.configure()
+ newScene.addSensor(newSensor)
+ newScene.setSensor(newSensor)
+ newScene.setSampler(scene.getSampler())
+ newScene.setDestinationFile(destination)
+
+ # Create a render job and insert it into the queue
+ job = RenderJob('myRenderJob' + str(i), newScene, queue, sceneResID)
+ job.start()
+
+# Wait for all jobs to finish and release resources
+# It works when this is moved in the loop when only one job at a time is started
+queue.waitLeft(0)
+queue.join()
+\end{python}
diff --git a/doc/section_bsdf.tex b/doc/section_bsdf.tex
index 2e835c94..26ed4ff3 100644
--- a/doc/section_bsdf.tex
+++ b/doc/section_bsdf.tex
@@ -4,10 +4,10 @@
\centering
\includegraphics[width=15.5cm]{images/bsdf_overview.pdf}
\caption{
- Schematic overview of the most important surface scattering models in
- Mitsuba (shown in the style of Weidlich and Wilkie \cite{Weidlich2007Arbitrarily}). The arrows indicate possible outcomes of an
- interaction with a surface that has the respective model applied to it.
- \vspace{4mm}
+ Schematic overview of the most important surface scattering models in
+ Mitsuba (shown in the style of Weidlich and Wilkie \cite{Weidlich2007Arbitrarily}). The arrows indicate possible outcomes of an
+ interaction with a surface that has the respective model applied to it.
+ \vspace{4mm}
}
\end{figure}
@@ -44,22 +44,22 @@ be named and then later referenced by their name.
The following fragment shows an example of both kinds of usages:
\begin{xml}
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
\end{xml}
It is generally more economical to use named BSDFs when they
@@ -72,13 +72,13 @@ memory usage.
\includegraphics[width=15cm]{images/glass_explanation.pdf}
\vspace{-5mm}
\caption{
- \label{fig:glass-explanation}
- Some of the scattering models in Mitsuba need to know
- the indices of refraction on the exterior and interior-facing
- side of a surface.
- It is therefore important to decompose the mesh into meaningful
- separate surfaces corresponding to each index of refraction change.
- The example here shows such a decomposition for a water-filled Glass.
+ \label{fig:glass-explanation}
+ Some of the scattering models in Mitsuba need to know
+ the indices of refraction on the exterior and interior-facing
+ side of a surface.
+ It is therefore important to decompose the mesh into meaningful
+ separate surfaces corresponding to each index of refraction change.
+ The example here shows such a decomposition for a water-filled Glass.
}
\end{figure}
diff --git a/doc/section_emitters.tex b/doc/section_emitters.tex
index 3ffb344f..99eb1bc2 100644
--- a/doc/section_emitters.tex
+++ b/doc/section_emitters.tex
@@ -9,7 +9,7 @@ types is shown below:
\centering
\includegraphics[width=15.5cm]{images/emitter_overview.pdf}
\caption{
- Schematic overview of the most important emitters in Mitsuba.
- The arrows indicate the directional distribution of light.
+ Schematic overview of the most important emitters in Mitsuba.
+ The arrows indicate the directional distribution of light.
}
\end{figure}
diff --git a/doc/section_films.tex b/doc/section_films.tex
index 325ec17d..eed5cef3 100644
--- a/doc/section_films.tex
+++ b/doc/section_films.tex
@@ -9,22 +9,22 @@ more scientifically oriented data formats (e.g. MATLAB or Mathematica).
In the XML scene description language, a normal film configuration might look as follows
\begin{xml}
-
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
\end{xml}
The \code{film} plugin should be instantiated nested inside a \code{sensor} declaration.
diff --git a/doc/section_integrators.tex b/doc/section_integrators.tex
index be1a7452..cf26a259 100644
--- a/doc/section_integrators.tex
+++ b/doc/section_integrators.tex
@@ -15,16 +15,16 @@ is usually instantiated by declaring it at the top level within the
scene, e.g.
\begin{xml}
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
\end{xml}
@@ -68,13 +68,13 @@ method (\pluginref{mlt}, \pluginref{erpt}).
\smallrendering{Max. depth = 3}{pathdepth-3}
\smallrendering{Max. depth = $\infty$}{pathdepth-all}
\caption{
- \label{fig:pathdepths}
- These Cornell box renderings demonstrate the visual
- effect of a maximum path depth. As the paths
- are allowed to grow longer, the color saturation
- increases due to multiple scattering interactions
- with the colored surfaces. At the same time, the
- computation time increases.
+ \label{fig:pathdepths}
+ These Cornell box renderings demonstrate the visual
+ effect of a maximum path depth. As the paths
+ are allowed to grow longer, the color saturation
+ increases due to multiple scattering interactions
+ with the colored surfaces. At the same time, the
+ computation time increases.
}
\end{figure}
@@ -94,10 +94,10 @@ depth unlimited.
\includegraphics[width=10cm]{images/path_explanation.pdf}
\vspace{-5mm}
\caption{
- \label{fig:path-explanation}
- A ray of emitted light is scattered by an object and subsequently
- reaches the eye/sensor.
- In Mitsuba, this is a \emph{depth-2} path, since it has two edges.
+ \label{fig:path-explanation}
+ A ray of emitted light is scattered by an object and subsequently
+ reaches the eye/sensor.
+ In Mitsuba, this is a \emph{depth-2} path, since it has two edges.
}
\end{figure}
Mitsuba counts depths starting at $1$, which correspond to
diff --git a/doc/section_media.tex b/doc/section_media.tex
index 3a6a42ed..dbe1277e 100644
--- a/doc/section_media.tex
+++ b/doc/section_media.tex
@@ -3,16 +3,16 @@
\label{sec:media}
\vspace{-1cm}
\renderings{
- \subfloat[A knitted sheep sweater (Ridged Feather pattern)]{
- \fbox{\includegraphics[width=0.58\textwidth]{images/medium_sheep}}}\hfill
- \subfloat[A knitted sweater for an alien character (Braid Cables pattern)]{
- \fbox{\includegraphics[width=0.32\textwidth]{images/medium_alien_cables}}}\hfill
- \vspace{-2mm}
- \caption{Participating media are not limited to smoke or fog: they are
- also great for rendering fuzzy materials such as these knitted sweaters
- (made using the \pluginref{heterogeneous} and \pluginref{microflake} plugins).
- Figure courtesy of Yuksel et al. \cite{Yuksel2012Stitch}, models courtesy of
- Rune Spaans and Christer Sveen.}
+ \subfloat[A knitted sheep sweater (Ridged Feather pattern)]{
+ \fbox{\includegraphics[width=0.58\textwidth]{images/medium_sheep}}}\hfill
+ \subfloat[A knitted sweater for an alien character (Braid Cables pattern)]{
+ \fbox{\includegraphics[width=0.32\textwidth]{images/medium_alien_cables}}}\hfill
+ \vspace{-2mm}
+ \caption{Participating media are not limited to smoke or fog: they are
+ also great for rendering fuzzy materials such as these knitted sweaters
+ (made using the \pluginref{heterogeneous} and \pluginref{microflake} plugins).
+ Figure courtesy of Yuksel et al. \cite{Yuksel2012Stitch}, models courtesy of
+ Rune Spaans and Christer Sveen.}
}
In Mitsuba, participating media are used to simulate materials ranging from
fog, smoke, and clouds, over translucent materials such as skin or milk,
@@ -31,14 +31,14 @@ referencing mechanism:
\begin{xml}
-
+
-
+
-
-
+
+
\end{xml}
diff --git a/doc/section_rfilters.tex b/doc/section_rfilters.tex
index 78861546..ecdcfb3c 100644
--- a/doc/section_rfilters.tex
+++ b/doc/section_rfilters.tex
@@ -72,23 +72,23 @@ Here, a high frequency function is reconstructed at low resolutions. A good filt
resolution and attenuate the remainder to a uniform gray. The filters are ordered by their
approximate level of success at this benchmark.
\renderings{
- \subfloat[A high resolution input image whose frequency decreases
- towards the borders. If you are looking at this on a computer, you may
- have to zoom in.]{\fbox{\includegraphics[width=0.43\textwidth]{images/rfilter_sines_input}}}
- \hfill
+ \subfloat[A high resolution input image whose frequency decreases
+ towards the borders. If you are looking at this on a computer, you may
+ have to zoom in.]{\fbox{\includegraphics[width=0.43\textwidth]{images/rfilter_sines_input}}}
+ \hfill
}
\vspace{-4mm}
\renderings{
- \medrendering{Box filter}{rfilter_sines_box}
- \medrendering{Tent filter}{rfilter_sines_tent}
- \medrendering{Gaussian filter}{rfilter_sines_gaussian}
+ \medrendering{Box filter}{rfilter_sines_box}
+ \medrendering{Tent filter}{rfilter_sines_tent}
+ \medrendering{Gaussian filter}{rfilter_sines_gaussian}
}
\vspace{-4mm}
\renderings{
- \setcounter{subfigure}{3}
- \medrendering{Mitchell-Netravali filter}{rfilter_sines_mitchell}
- \medrendering{Catmull-Rom filter}{rfilter_sines_catmullrom}
- \medrendering{Lanczos Sinc filter}{rfilter_sines_lanczos}
+ \setcounter{subfigure}{3}
+ \medrendering{Mitchell-Netravali filter}{rfilter_sines_mitchell}
+ \medrendering{Catmull-Rom filter}{rfilter_sines_catmullrom}
+ \medrendering{Lanczos Sinc filter}{rfilter_sines_lanczos}
}
\newpage
\subsubsection{Reconstruction filter comparison 2: ringing}
@@ -97,39 +97,39 @@ image contains extreme and discontinuous brightness transitions. The
Mitchell-Netravali, Catmull-Rom, and Lanczos Sinc filters are affected by this problem.
Note the black fringing around the light source in the cropped Cornell box renderings below.
\renderings{
- \rendering{Box filter}{rfilter_cbox_box}
- \rendering{Tent filter}{rfilter_cbox_tent}
+ \rendering{Box filter}{rfilter_cbox_box}
+ \rendering{Tent filter}{rfilter_cbox_tent}
}
\vspace{-4mm}
\renderings{
- \setcounter{subfigure}{2}
- \rendering{Gaussian filter}{rfilter_cbox_gaussian}
- \rendering{Mitchell-Netravali filter}{rfilter_cbox_mitchell}
+ \setcounter{subfigure}{2}
+ \rendering{Gaussian filter}{rfilter_cbox_gaussian}
+ \rendering{Mitchell-Netravali filter}{rfilter_cbox_mitchell}
}
\vspace{-4mm}
\renderings{
- \setcounter{subfigure}{4}
- \rendering{Catmull-Rom filter}{rfilter_cbox_catmullrom}
- \rendering{Lanczos Sinc filter}{rfilter_cbox_lanczos}
+ \setcounter{subfigure}{4}
+ \rendering{Catmull-Rom filter}{rfilter_cbox_catmullrom}
+ \rendering{Lanczos Sinc filter}{rfilter_cbox_lanczos}
}
\subsubsection{Specifying a reconstruction filter}
To specify a reconstruction filter, it must be instantiated inside
the sensor's film. Below is an example:
\begin{xml}
-
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
\end{xml}
diff --git a/doc/section_shapes.tex b/doc/section_shapes.tex
index ca8582a8..5ea219dd 100644
--- a/doc/section_shapes.tex
+++ b/doc/section_shapes.tex
@@ -13,19 +13,19 @@ This BSDF characterizes what happens \emph{at the surface}. In the XML scene des
the following:
\begin{xml}
-
- ... $\code{shape}$ parameters ...
+
+ ... $\code{shape}$ parameters ...
-
- ... $\code{bsdf}$ parameters ..
-
+
+ ... $\code{bsdf}$ parameters ..
+
-
-
+ -->
+
\end{xml}
@@ -35,24 +35,24 @@ of the shape. This informs the renderer about what happens in the region of spac
\begin{xml}
-
- ... $\code{shape}$ parameters ...
+
+ ... $\code{shape}$ parameters ...
-
- ... $\code{medium}$ parameters ...
-
+
+ ... $\code{medium}$ parameters ...
+
-
- ... $\code{medium}$ parameters ...
-
+
+ ... $\code{medium}$ parameters ...
+
-
-
+ -->
+
\end{xml}
@@ -66,29 +66,29 @@ It is also possible to create \emph{index-mismatched} boundaries between media,
the light is affected by the boundary transition:
\begin{xml}
-
- ... $\code{shape}$ parameters ...
+
+ ... $\code{shape}$ parameters ...
-
- ... $\code{bsdf}$ parameters ..
-
+
+ ... $\code{bsdf}$ parameters ..
+
-
- ... $\code{medium}$ parameters ...
-
+
+ ... $\code{medium}$ parameters ...
+
-
- ... $\code{medium}$ parameters ...
-
+
+ ... $\code{medium}$ parameters ...
+
-
-
+ -->
+
\end{xml}
This constitutes the standard ways in which a shape can be declared.