got rid of exrtexture, renamed ldrtexture to bitmap and extended it to handle EXRs.
parent
38a908306e
commit
c4eaf13ec8
|
@ -10,12 +10,16 @@ An simple scene with a single mesh and the default lighting and camera setup mig
|
|||
something like this:
|
||||
\begin{xml}
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<scene>
|
||||
<scene version=$\MtsVer$>
|
||||
<shape type="obj">
|
||||
<string name="filename" value="dragon.obj"/>
|
||||
</shape>
|
||||
</scene>
|
||||
\end{xml}
|
||||
The scene version attribute denotes the release of Mitsuba that was used to
|
||||
create the scene. This information allows Mitsuba to always correctly process the
|
||||
file irregardless of any potential future changes in the scene description language.
|
||||
|
||||
This example already contains the most important things to know about format: you can have
|
||||
\emph{objects} (such as the objects instantiated by the \code{scene} or \code{shape} tags), which are allowed to be nested within
|
||||
each other. Each object optionally accepts \emph{properties} (such as the \code{string} tag),
|
||||
|
@ -29,7 +33,7 @@ the certainly case for the plugin named \code{obj} (it contains a WaveFront OBJ
|
|||
Similarly, you could write
|
||||
\begin{xml}
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<scene>
|
||||
<scene version=$\MtsVer$>
|
||||
<shape type="sphere">
|
||||
<float name="radius" value="10"/>
|
||||
</shape>
|
||||
|
@ -43,7 +47,7 @@ The most common scene setup is to declare an integrator, some geometry, a camera
|
|||
and one or more luminaires. Here is a more complex example:
|
||||
\begin{xml}
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<scene>
|
||||
<scene version=$\MtsVer$>
|
||||
<integrator type="path"> <!-- Path trace an 8-bounce GI solution -->
|
||||
<integer name="maxDepth" value="8"/>
|
||||
</integrator>
|
||||
|
@ -202,8 +206,8 @@ Quite often, you will find yourself using an object (such as a material) in many
|
|||
to declare it over and over again, which wastes memory, you can make use of references. Here is an example
|
||||
of how this works:
|
||||
\begin{xml}
|
||||
<scene>
|
||||
<texture type="ldrtexture" id="myImage">
|
||||
<scene version=$\MtsVer$>
|
||||
<texture type="bitmap" id="myImage">
|
||||
<string name="filename" value="textures/myImage.jpg"/>
|
||||
</texture>
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 146 KiB |
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
|
@ -44,13 +44,14 @@
|
|||
|
||||
\newcommand{\renderings}[1]{
|
||||
\begin{figure}[h!]
|
||||
\setcounter{subfigure}{0}
|
||||
\centering
|
||||
\hfill
|
||||
#1
|
||||
\end{figure}
|
||||
}
|
||||
|
||||
\newcommand{\rendering}[2]{\subfigure[#1]{\fbox{\includegraphics[width=0.4\textwidth]{images/#2}}}\hfill}
|
||||
\newcommand{\rendering}[2]{\subfigure[#1]{\fbox{\includegraphics[width=0.47\textwidth]{images/#2}}}\hfill}
|
||||
\newcommand{\medrendering}[2]{ \subfigure[#1]{\fbox{\includegraphics[width=0.3\textwidth]{images/#2}}}\hfill}
|
||||
\newcommand{\smallrendering}[2]{ \subfigure[#1]{\fbox{\includegraphics[width=0.2\textwidth]{images/#2}}}\hfill}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ either be performed by nesting BSDFs within shapes, or they can
|
|||
be named and then later referenced by their name.
|
||||
The following fragment shows an example of both kinds of usages:
|
||||
\begin{xml}
|
||||
<scene>
|
||||
<scene version=$\MtsVer$>
|
||||
<!-- Creating a named BSDF for later use -->
|
||||
<bsdf type=".. BSDF type .." id="myNamedMaterial">
|
||||
<!-- BSDF parameters go here -->
|
||||
|
|
|
@ -53,8 +53,8 @@ MTS_NAMESPACE_BEGIN
|
|||
* \end{xml}
|
||||
* \begin{xml}[caption=Lambertian material with a texture map, label=lst:lambertian-textured]
|
||||
* <bsdf type="lambertian">
|
||||
* <texture type="ldrtexture" name="reflectance">
|
||||
* <string name="filename" value="wood.jpg"/>
|
||||
* <texture type="bitmap" name="reflectance">
|
||||
* <string name="filename" value="wood.jpg"/>
|
||||
* </texture>
|
||||
* </bsdf>
|
||||
* \end{xml}
|
||||
|
|
|
@ -57,8 +57,8 @@ MTS_NAMESPACE_BEGIN
|
|||
*
|
||||
* \begin{xml}[caption=Lambertian material with a texture map, label=lst:lambertian-textured]
|
||||
* <bsdf type="lambertian">
|
||||
* <texture type="ldrtexture" name="reflectance">
|
||||
* <string name="filename" value="wood.jpg"/>
|
||||
* <texture type="bitmap" name="reflectance">
|
||||
* <string name="filename" value="wood.jpg"/>
|
||||
* </texture>
|
||||
* </bsdf>
|
||||
* \end{xml}
|
||||
|
|
|
@ -30,7 +30,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* used to model the surface roughness.
|
||||
* \begin{enumerate}[(i)]
|
||||
* \item \code{beckmann}: Physically-based distribution derived from
|
||||
* Gaussian random surfaces. This is the default choice.
|
||||
* Gaussian random surfaces. This is the default.
|
||||
* \item \code{phong}: Classical $\cos^p\theta$ distribution.
|
||||
* The Phong exponent $p$ is obtained using a transformation that
|
||||
* produces roughness similar to a Beckmann distribution of the same
|
||||
|
@ -55,35 +55,62 @@ MTS_NAMESPACE_BEGIN
|
|||
* \parameter{extIOR}{\Float}{Exterior index of refraction \default{1.0}}
|
||||
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
|
||||
* factor used to modulate the reflectance component\default{1.0}}
|
||||
* \parameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional
|
||||
* \lastparameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional
|
||||
* factor used to modulate the transmittance component\default{1.0}}
|
||||
* }
|
||||
*
|
||||
* \renderings{
|
||||
* \medrendering{Beckmann, $\alpha$=0.2}{bsdf_dielectric_glass}
|
||||
* \medrendering{Beckmann, $\alpha$=0.3}{bsdf_dielectric_glass}
|
||||
* \medrendering{Beckmann, $\alpha$=0.4}{bsdf_dielectric_glass}
|
||||
* }
|
||||
*
|
||||
* This plugin implements a realistic microfacet scattering model for rendering
|
||||
* rough interfaces between dielectric materials, such as a transition from air to ground glass.
|
||||
* Microfacet theory describes surfaces as an arrangement of unresolved and ideally specular
|
||||
* facets, whose normals are given by a specially chosen \emph{microfacet
|
||||
* distribution}. By accounting for shadowing and masking effects between
|
||||
* these facets, it is possible to reproduce the off-specular reflections
|
||||
* peaks observed in real-world measurements of such materials.
|
||||
* rough interfaces between dielectric materials, such as a transition from air to
|
||||
* ground glass. Microfacet theory describes rough surfaces as an arrangement of
|
||||
* unresolved and ideally specular facets, whose normal directions are given by
|
||||
* a specially chosen \emph{microfacet distribution}. By accounting for shadowing
|
||||
* and masking effects between these facets, it is possible to reproduce the
|
||||
* off-specular reflections peaks observed in real-world measurements of such
|
||||
* materials.
|
||||
* \renderings{
|
||||
* \rendering{Rough glass (Beckmann, $\alpha$=0.1)}{bsdf_roughdielectric_beckmann_0_1.jpg}
|
||||
* \rendering{Ground glass (GGX, $\alpha$=0.304, \lstref{roughdielectric-roughglass})}{bsdf_roughdielectric_ggx_0_304.jpg}
|
||||
* }
|
||||
*
|
||||
* This plugin is essentially the ``roughened'' equivalent of the plugin
|
||||
* \pluginref{dielectric}. Its implementation is based on the paper
|
||||
* ``Microfacet Models for Refraction through Rough Surfaces''
|
||||
* \cite{Walter07Microfacet}. The model supports several types of microfacet
|
||||
* distributions and a texturable roughness. The default settings are set
|
||||
* \pluginref{dielectric}. As the roughness value is decreased, it increasingly
|
||||
* approximates that model. Its implementation is based on the paper
|
||||
* ``Microfacet Models for Refraction through Rough Surfaces'' by Walter et
|
||||
* al. \cite{Walter07Microfacet}. The model supports several types of microfacet
|
||||
* distributions and has a texturable roughness parameter.
|
||||
* The default settings are set
|
||||
* to a borosilicate glass BK7/air interface with a light amount of rougness
|
||||
* modeled using a Beckmann distribution.
|
||||
*
|
||||
* When using this plugin, it is crucial that the scene contains
|
||||
* meaningful and mutally compatible index of refraction change -- see
|
||||
* \figref{glass-explanation} for an example.
|
||||
* meaningful and mutally compatible index of refraction change---see
|
||||
* \figref{glass-explanation} for an example. Also, please note that
|
||||
* the importance sampling implementation of this model is close, but
|
||||
* not perfect a perfect match to the underlying scattering distribution,
|
||||
* particularly for high roughness values and when the \texttt{GGX}
|
||||
* model is used. Hence, such renderings may converge slowly.
|
||||
*
|
||||
* \begin{xml}[caption=Ground glass, label=lst:roughdielectric-roughglass]
|
||||
* <bsdf type="roughdielectric">
|
||||
* <string name="distribution" value="ggx"/>
|
||||
* <float name="alpha" value="0.304"/>
|
||||
* <float name="intIOR" value="1.5046"/>
|
||||
* <float name="extIOR" value="1.0"/>
|
||||
* </bsdf>
|
||||
* \end{xml}
|
||||
*
|
||||
* \begin{xml}[caption=Textured rougness, label=lst:roughdielectric-textured]
|
||||
* <bsdf type="roughdielectric">
|
||||
* <string name="distribution" value="beckmann"/>
|
||||
* <float name="intIOR" value="1.5046"/>
|
||||
* <float name="extIOR" value="1.0"/>
|
||||
*
|
||||
* <texture type="bitmap" name="alpha">
|
||||
* <string name="filename" value="roughness.exr"/>
|
||||
* </texture>
|
||||
* </bsdf>
|
||||
* \end{xml}
|
||||
*/
|
||||
class RoughDielectric : public BSDF {
|
||||
public:
|
||||
|
@ -384,7 +411,8 @@ public:
|
|||
}
|
||||
|
||||
/* Evaluate the roughness */
|
||||
const Float alpha = m_alpha->getValue(bRec.its).average();
|
||||
const Float alpha =
|
||||
std::max(m_alpha->getValue(bRec.its).average(), (Float) 1e-4f);
|
||||
|
||||
/* Microsurface normal distribution */
|
||||
const Float D = evalD(H, alpha);
|
||||
|
@ -467,7 +495,8 @@ public:
|
|||
}
|
||||
|
||||
/* Evaluate the roughness */
|
||||
Float alpha = m_alpha->getValue(bRec.its).average();
|
||||
Float alpha =
|
||||
std::max(m_alpha->getValue(bRec.its).average(), (Float) 1e-4f);
|
||||
|
||||
/* Suggestion by Bruce Walter: sample using a slightly different
|
||||
value of alpha. This in practice limits the weights to
|
||||
|
@ -549,7 +578,8 @@ public:
|
|||
}
|
||||
|
||||
/* Evaluate the roughness */
|
||||
Float alpha = m_alpha->getValue(bRec.its).average();
|
||||
Float alpha =
|
||||
std::max(m_alpha->getValue(bRec.its).average(), (Float) 1e-4f);
|
||||
|
||||
/* Suggestion by Bruce Walter: sample using a slightly different
|
||||
value of alpha. This in practice limits the weights to
|
||||
|
@ -671,7 +701,8 @@ public:
|
|||
}
|
||||
|
||||
/* Evaluate the roughness */
|
||||
Float alpha = m_alpha->getValue(bRec.its).average();
|
||||
Float alpha =
|
||||
std::max(m_alpha->getValue(bRec.its).average(), (Float) 1e-4f);
|
||||
|
||||
/* Suggestion by Bruce Walter: sample using a slightly different
|
||||
value of alpha. This in practice limits the weights to
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
Import('env', 'plugins')
|
||||
|
||||
plugins += env.SharedLibrary('exrtexture', ['exrtexture.cpp'])
|
||||
plugins += env.SharedLibrary('ldrtexture', ['ldrtexture.cpp'])
|
||||
plugins += env.SharedLibrary('bitmap', ['bitmap.cpp'])
|
||||
plugins += env.SharedLibrary('gridtexture', ['gridtexture.cpp'])
|
||||
plugins += env.SharedLibrary('checkerboard', ['checkerboard.cpp'])
|
||||
plugins += env.SharedLibrary('vertexcolors', ['vertexcolors.cpp'])
|
||||
|
|
|
@ -31,14 +31,17 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* Gamma-corrected bitmap texture using the JPG, PNG, TGA or BMP
|
||||
* Gamma-corrected bitmap texture using the EXR, JPG, PNG, TGA or BMP
|
||||
* file formats.
|
||||
*/
|
||||
class LDRTexture : public Texture2D {
|
||||
class BitmapTexture : public Texture2D {
|
||||
public:
|
||||
LDRTexture(const Properties &props) : Texture2D(props) {
|
||||
BitmapTexture(const Properties &props) : Texture2D(props) {
|
||||
m_filename = Thread::getThread()->getFileResolver()->resolve(
|
||||
props.getString("filename"));
|
||||
m_gamma = props.getFloat("gamma", -1); /* -1 means sRGB */
|
||||
|
||||
/* -1 means sRGB. Gamma is ignored when loading EXR files */
|
||||
m_gamma = props.getFloat("gamma", -1);
|
||||
Log(EInfo, "Loading texture \"%s\"", m_filename.leaf().c_str());
|
||||
|
||||
ref<FileStream> fs = new FileStream(m_filename, FileStream::EReadOnly);
|
||||
|
@ -71,7 +74,9 @@ public:
|
|||
|
||||
m_maxAnisotropy = props.getFloat("maxAnisotropy", 8);
|
||||
|
||||
if (extension == ".jpg" || extension == ".jpeg")
|
||||
if (extension == ".exr")
|
||||
m_format = Bitmap::EEXR;
|
||||
else if (extension == ".jpg" || extension == ".jpeg")
|
||||
m_format = Bitmap::EJPEG;
|
||||
else if (extension == ".png")
|
||||
m_format = Bitmap::EPNG;
|
||||
|
@ -86,7 +91,7 @@ public:
|
|||
initializeFrom(bitmap);
|
||||
}
|
||||
|
||||
LDRTexture(Stream *stream, InstanceManager *manager)
|
||||
BitmapTexture(Stream *stream, InstanceManager *manager)
|
||||
: Texture2D(stream, manager) {
|
||||
m_filename = stream->readString();
|
||||
Log(EInfo, "Unserializing texture \"%s\"", m_filename.leaf().c_str());
|
||||
|
@ -121,84 +126,91 @@ public:
|
|||
}
|
||||
|
||||
void initializeFrom(Bitmap *bitmap) {
|
||||
ref<Bitmap> corrected = new Bitmap(bitmap->getWidth(), bitmap->getHeight(), 128);
|
||||
|
||||
float tbl[256];
|
||||
if (m_gamma == -1) {
|
||||
for (int i=0; i<256; ++i)
|
||||
tbl[i] = fromSRGBComponent((Float) i / (Float) 255);
|
||||
ref<Bitmap> corrected;
|
||||
m_bpp = bitmap->getBitsPerPixel();
|
||||
if (bitmap->getBitsPerPixel() == 128) {
|
||||
/* Nothing needs to be done */
|
||||
corrected = bitmap;
|
||||
} else {
|
||||
for (int i=0; i<256; ++i)
|
||||
tbl[i] = std::pow((Float) i / (Float) 255, m_gamma);
|
||||
}
|
||||
corrected = new Bitmap(bitmap->getWidth(), bitmap->getHeight(), 128);
|
||||
|
||||
uint8_t *data = bitmap->getData();
|
||||
float *flData = corrected->getFloatData();
|
||||
if (bitmap->getBitsPerPixel() == 32) {
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
float
|
||||
r = tbl[*data++],
|
||||
g = tbl[*data++],
|
||||
b = tbl[*data++],
|
||||
a = *data++ / 255.0f;
|
||||
*flData++ = r;
|
||||
*flData++ = g;
|
||||
*flData++ = b;
|
||||
*flData++ = a;
|
||||
}
|
||||
float tbl[256];
|
||||
if (m_gamma == -1) {
|
||||
for (int i=0; i<256; ++i)
|
||||
tbl[i] = fromSRGBComponent((Float) i / (Float) 255);
|
||||
} else {
|
||||
for (int i=0; i<256; ++i)
|
||||
tbl[i] = std::pow((Float) i / (Float) 255, m_gamma);
|
||||
}
|
||||
} else if (bitmap->getBitsPerPixel() == 24) {
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
float
|
||||
r = tbl[*data++],
|
||||
g = tbl[*data++],
|
||||
b = tbl[*data++];
|
||||
*flData++ = r;
|
||||
*flData++ = g;
|
||||
*flData++ = b;
|
||||
*flData++ = 1.0f;
|
||||
|
||||
uint8_t *data = bitmap->getData();
|
||||
float *flData = corrected->getFloatData();
|
||||
if (bitmap->getBitsPerPixel() == 32) {
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
float
|
||||
r = tbl[*data++],
|
||||
g = tbl[*data++],
|
||||
b = tbl[*data++],
|
||||
a = *data++ / 255.0f;
|
||||
*flData++ = r;
|
||||
*flData++ = g;
|
||||
*flData++ = b;
|
||||
*flData++ = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (bitmap->getBitsPerPixel() == 16) {
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
float col = tbl[*data++],
|
||||
a = *data++ / 255.0f;
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = a;
|
||||
} else if (bitmap->getBitsPerPixel() == 24) {
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
float
|
||||
r = tbl[*data++],
|
||||
g = tbl[*data++],
|
||||
b = tbl[*data++];
|
||||
*flData++ = r;
|
||||
*flData++ = g;
|
||||
*flData++ = b;
|
||||
*flData++ = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (bitmap->getBitsPerPixel() == 8) {
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
float col = tbl[*data++];
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = 1.0f;
|
||||
} else if (bitmap->getBitsPerPixel() == 16) {
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
float col = tbl[*data++],
|
||||
a = *data++ / 255.0f;
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (bitmap->getBitsPerPixel() == 1) {
|
||||
int pos = 0;
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
int entry = pos / 8;
|
||||
int bit = pos % 8;
|
||||
int value = (data[entry] & (1 << bit)) ? 255 : 0;
|
||||
float col = tbl[value];
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = 1.0f;
|
||||
pos++;
|
||||
} else if (bitmap->getBitsPerPixel() == 8) {
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
float col = tbl[*data++];
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = 1.0f;
|
||||
}
|
||||
}
|
||||
} else if (bitmap->getBitsPerPixel() == 1) {
|
||||
int pos = 0;
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
int entry = pos / 8;
|
||||
int bit = pos % 8;
|
||||
int value = (data[entry] & (1 << bit)) ? 255 : 0;
|
||||
float col = tbl[value];
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = 1.0f;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log(EError, "%i bpp images are currently not supported!", bitmap->getBitsPerPixel());
|
||||
}
|
||||
} else {
|
||||
Log(EError, "%i bpp images are currently not supported!", bitmap->getBitsPerPixel());
|
||||
}
|
||||
|
||||
m_mipmap = MIPMap::fromBitmap(corrected, m_filterType,
|
||||
|
@ -258,10 +270,16 @@ public:
|
|||
|
||||
std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "LDRTexture[" << endl
|
||||
oss << "BitmapTexture[" << endl
|
||||
<< " filename = \"" << m_filename << "\"," << endl
|
||||
<< " gamma = " << m_gamma << endl
|
||||
<< "]";
|
||||
<< " bpp = " << m_bpp;
|
||||
if (m_bpp < 128) {
|
||||
oss << "," << endl
|
||||
<< " gamma = " << m_gamma << endl;
|
||||
} else {
|
||||
oss << endl;
|
||||
}
|
||||
oss << "]";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
@ -278,13 +296,14 @@ protected:
|
|||
Float m_gamma;
|
||||
MIPMap::EWrapMode m_wrapMode;
|
||||
Float m_maxAnisotropy;
|
||||
int m_bpp;
|
||||
};
|
||||
|
||||
// ================ Hardware shader implementation ================
|
||||
|
||||
class LDRTextureShader : public Shader {
|
||||
class BitmapTextureShader : public Shader {
|
||||
public:
|
||||
LDRTextureShader(Renderer *renderer, std::string filename, ref<Bitmap> bitmap,
|
||||
BitmapTextureShader(Renderer *renderer, std::string filename, ref<Bitmap> bitmap,
|
||||
const Point2 &uvOffset, const Vector2 &uvScale, MIPMap::EWrapMode wrapMode,
|
||||
Float maxAnisotropy)
|
||||
: Shader(renderer, ETextureShader), m_uvOffset(uvOffset), m_uvScale(uvScale) {
|
||||
|
@ -342,14 +361,14 @@ private:
|
|||
Vector2 m_uvScale;
|
||||
};
|
||||
|
||||
Shader *LDRTexture::createShader(Renderer *renderer) const {
|
||||
return new LDRTextureShader(renderer, m_filename.leaf(),
|
||||
Shader *BitmapTexture::createShader(Renderer *renderer) const {
|
||||
return new BitmapTextureShader(renderer, m_filename.leaf(),
|
||||
m_mipmap->getLDRBitmap(), m_uvOffset, m_uvScale,
|
||||
m_wrapMode, (m_filterType == MIPMap::EEWA)
|
||||
? m_maxAnisotropy : 1.0f);
|
||||
}
|
||||
|
||||
MTS_IMPLEMENT_CLASS_S(LDRTexture, false, Texture2D)
|
||||
MTS_IMPLEMENT_CLASS(LDRTextureShader, false, Shader)
|
||||
MTS_EXPORT_PLUGIN(LDRTexture, "LDR texture (JPG/PNG/TGA/BMP)");
|
||||
MTS_IMPLEMENT_CLASS_S(BitmapTexture, false, Texture2D)
|
||||
MTS_IMPLEMENT_CLASS(BitmapTextureShader, false, Shader)
|
||||
MTS_EXPORT_PLUGIN(BitmapTexture, "Bitmap texture (EXR/JPG/PNG/TGA/BMP)");
|
||||
MTS_NAMESPACE_END
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
This file is part of Mitsuba, a physically based rendering system.
|
||||
|
||||
Copyright (c) 2007-2011 by Wenzel Jakob and others.
|
||||
|
||||
Mitsuba is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License Version 3
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
Mitsuba is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <mitsuba/core/bitmap.h>
|
||||
#include <mitsuba/core/mstream.h>
|
||||
#include <mitsuba/core/fstream.h>
|
||||
#include <mitsuba/core/fresolver.h>
|
||||
#include <mitsuba/core/properties.h>
|
||||
#include <mitsuba/render/texture.h>
|
||||
#include <mitsuba/render/mipmap.h>
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* Simple linear (i.e. not gamma corrected) bitmap texture
|
||||
* using the EXR file format
|
||||
*/
|
||||
class EXRTexture : public Texture2D {
|
||||
public:
|
||||
EXRTexture(const Properties &props) : Texture2D(props) {
|
||||
m_filename = Thread::getThread()->getFileResolver()->resolve(
|
||||
props.getString("filename"));
|
||||
Log(EInfo, "Loading texture \"%s\"", m_filename.leaf().c_str());
|
||||
|
||||
ref<FileStream> fs = new FileStream(m_filename, FileStream::EReadOnly);
|
||||
ref<Bitmap> bitmap = new Bitmap(Bitmap::EEXR, fs);
|
||||
m_mipmap = MIPMap::fromBitmap(bitmap);
|
||||
m_average = m_mipmap->triangle(m_mipmap->getLevels()-1, 0, 0);
|
||||
m_maximum = m_mipmap->getMaximum();
|
||||
}
|
||||
|
||||
EXRTexture(Stream *stream, InstanceManager *manager)
|
||||
: Texture2D(stream, manager) {
|
||||
m_filename = stream->readString();
|
||||
Log(EInfo, "Unserializing texture \"%s\"", m_filename.leaf().c_str());
|
||||
size_t size = stream->readSize();
|
||||
ref<MemoryStream> mStream = new MemoryStream(size);
|
||||
stream->copyTo(mStream, size);
|
||||
mStream->setPos(0);
|
||||
ref<Bitmap> bitmap = new Bitmap(Bitmap::EEXR, mStream);
|
||||
m_mipmap = MIPMap::fromBitmap(bitmap);
|
||||
m_average = m_mipmap->triangle(m_mipmap->getLevels()-1, 0, 0);
|
||||
m_maximum = m_mipmap->getMaximum();
|
||||
}
|
||||
|
||||
void serialize(Stream *stream, InstanceManager *manager) const {
|
||||
Texture2D::serialize(stream, manager);
|
||||
stream->writeString(m_filename.file_string());
|
||||
ref<Stream> is = new FileStream(m_filename, FileStream::EReadOnly);
|
||||
stream->writeSize(is->getSize());
|
||||
is->copyTo(stream);
|
||||
}
|
||||
|
||||
Spectrum getValue(const Point2 &uv) const {
|
||||
return m_mipmap->triangle(0, uv.x, uv.y);
|
||||
}
|
||||
|
||||
Spectrum getValue(const Point2 &uv, Float dudx,
|
||||
Float dudy, Float dvdx, Float dvdy) const {
|
||||
return m_mipmap->getValue(uv.x, uv.y, dudx, dudy, dvdx, dvdy);
|
||||
}
|
||||
|
||||
Spectrum getMaximum() const {
|
||||
return m_maximum;
|
||||
}
|
||||
|
||||
Spectrum getAverage() const {
|
||||
return m_average;
|
||||
}
|
||||
|
||||
bool usesRayDifferentials() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector3i getResolution() const {
|
||||
return Vector3i(
|
||||
m_mipmap->getWidth(),
|
||||
m_mipmap->getHeight(),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "EXRTexture[filename=\"" << m_filename.file_string() << "\"]";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
protected:
|
||||
ref<MIPMap> m_mipmap;
|
||||
fs::path m_filename;
|
||||
Spectrum m_average, m_maximum;
|
||||
};
|
||||
|
||||
MTS_IMPLEMENT_CLASS_S(EXRTexture, false, Texture2D)
|
||||
MTS_EXPORT_PLUGIN(EXRTexture, "HDR texture (EXR)");
|
||||
MTS_NAMESPACE_END
|
Loading…
Reference in New Issue