improved interface for ensuring energy conservation
parent
8dbb6327f4
commit
736a8e6866
|
@ -2,8 +2,7 @@
|
||||||
to be tested for consistency. This is done
|
to be tested for consistency. This is done
|
||||||
using the testcase 'test_chisquare' -->
|
using the testcase 'test_chisquare' -->
|
||||||
<scene>
|
<scene>
|
||||||
|
<!-- Test the rough dielectric model with the anisotropic
|
||||||
<!-- Test the rough glass model with the
|
|
||||||
Ashikhmin-Shirley microfacet distribution -->
|
Ashikhmin-Shirley microfacet distribution -->
|
||||||
<bsdf type="roughdielectric">
|
<bsdf type="roughdielectric">
|
||||||
<string name="distribution" value="as"/>
|
<string name="distribution" value="as"/>
|
||||||
|
@ -19,15 +18,6 @@
|
||||||
<string name="extIOR" value="air"/>
|
<string name="extIOR" value="air"/>
|
||||||
</bsdf>
|
</bsdf>
|
||||||
|
|
||||||
<!-- Test the rough glass model with the
|
|
||||||
Beckmann microfacet distribution -->
|
|
||||||
<bsdf type="roughdielectric">
|
|
||||||
<string name="distribution" value="beckmann"/>
|
|
||||||
<float name="alpha" value=".3"/>
|
|
||||||
<float name="intIOR" value="1.5"/>
|
|
||||||
<float name="extIOR" value="1.0"/>
|
|
||||||
</bsdf>
|
|
||||||
|
|
||||||
<!-- Test the diffuse model -->
|
<!-- Test the diffuse model -->
|
||||||
<bsdf type="diffuse"/>
|
<bsdf type="diffuse"/>
|
||||||
|
|
||||||
|
@ -49,4 +39,41 @@
|
||||||
|
|
||||||
<!-- Test the conductor model -->
|
<!-- Test the conductor model -->
|
||||||
<bsdf type="conductor"/>
|
<bsdf type="conductor"/>
|
||||||
|
|
||||||
|
<!-- Test the rough glass model with the
|
||||||
|
Beckmann microfacet distribution -->
|
||||||
|
<bsdf type="roughdielectric">
|
||||||
|
<string name="distribution" value="beckmann"/>
|
||||||
|
<float name="alpha" value=".3"/>
|
||||||
|
<float name="intIOR" value="1.5"/>
|
||||||
|
<float name="extIOR" value="1.0"/>
|
||||||
|
</bsdf>
|
||||||
|
|
||||||
|
<!-- Test the rough glass model with the
|
||||||
|
Phong microfacet distribution -->
|
||||||
|
<bsdf type="roughdielectric">
|
||||||
|
<string name="distribution" value="phong"/>
|
||||||
|
<float name="alpha" value=".3"/>
|
||||||
|
<float name="intIOR" value="1.5"/>
|
||||||
|
<float name="extIOR" value="1.0"/>
|
||||||
|
</bsdf>
|
||||||
|
|
||||||
|
<!-- Test the rough glass model with the
|
||||||
|
GGX microfacet distribution -->
|
||||||
|
<bsdf type="roughdielectric">
|
||||||
|
<string name="distribution" value="ggx"/>
|
||||||
|
<float name="alpha" value=".3"/>
|
||||||
|
<float name="intIOR" value="1.5"/>
|
||||||
|
<float name="extIOR" value="1.0"/>
|
||||||
|
</bsdf>
|
||||||
|
|
||||||
|
<!-- Test the rough dielectric model with the anisotropic
|
||||||
|
Ashikhmin-Shirley microfacet distribution -->
|
||||||
|
<bsdf type="roughdielectric">
|
||||||
|
<string name="distribution" value="as"/>
|
||||||
|
<float name="alphaU" value=".1"/>
|
||||||
|
<float name="alphaV" value=".3"/>
|
||||||
|
<float name="intIOR" value="1.5"/>
|
||||||
|
<float name="extIOR" value="1.0"/>
|
||||||
|
</bsdf>
|
||||||
</scene>
|
</scene>
|
||||||
|
|
|
@ -422,12 +422,26 @@ protected:
|
||||||
/// Unserialize a BSDF instance
|
/// Unserialize a BSDF instance
|
||||||
BSDF(Stream *stream, InstanceManager *manager);
|
BSDF(Stream *stream, InstanceManager *manager);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Convenience function to ensure energy conservation
|
||||||
|
*
|
||||||
|
* This function determines the component-wise maximum of the
|
||||||
|
* texture \c tex and checks if it is below \c max. If yes,
|
||||||
|
* it returns the texture unmodified. Otherwise, it wraps
|
||||||
|
* the texture into a \ref ScaleTexture instance (with a
|
||||||
|
* scaling factor chosen so that the desired maximum \c max
|
||||||
|
* is abided) and prints a warning.
|
||||||
|
*/
|
||||||
|
Texture *ensureEnergyConservation(Texture *tex,
|
||||||
|
const std::string ¶mName, Float max) const;
|
||||||
|
|
||||||
/// Virtual destructor
|
/// Virtual destructor
|
||||||
virtual ~BSDF();
|
virtual ~BSDF();
|
||||||
protected:
|
protected:
|
||||||
std::vector<unsigned int> m_components;
|
std::vector<unsigned int> m_components;
|
||||||
unsigned int m_combinedType;
|
unsigned int m_combinedType;
|
||||||
bool m_usesRayDifferentials;
|
bool m_usesRayDifferentials;
|
||||||
|
bool m_ensureEnergyConservation;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,109 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(__CONST_TEXTURE_H)
|
|
||||||
#define __CONST_TEXTURE_H
|
|
||||||
|
|
||||||
#include <mitsuba/core/properties.h>
|
|
||||||
#include <mitsuba/render/texture.h>
|
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
class MTS_EXPORT_RENDER ConstantSpectrumTexture : public Texture {
|
|
||||||
public:
|
|
||||||
inline ConstantSpectrumTexture(const Spectrum &value)
|
|
||||||
: Texture(Properties()), m_value(value) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstantSpectrumTexture(Stream *stream, InstanceManager *manager);
|
|
||||||
|
|
||||||
inline Spectrum getValue(const Intersection &its) const {
|
|
||||||
return m_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Spectrum getAverage() const {
|
|
||||||
return m_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Spectrum getMaximum() const {
|
|
||||||
return m_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string toString() const {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "ConstantSpectrumTexture[value=" << m_value.toString() << "]";
|
|
||||||
return oss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool usesRayDifferentials() const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Shader *createShader(Renderer *renderer) const;
|
|
||||||
|
|
||||||
void serialize(Stream *stream, InstanceManager *manager) const;
|
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
|
||||||
protected:
|
|
||||||
Spectrum m_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
class MTS_EXPORT_RENDER ConstantFloatTexture : public Texture {
|
|
||||||
public:
|
|
||||||
inline ConstantFloatTexture(const Float &value)
|
|
||||||
: Texture(Properties()), m_value(value) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstantFloatTexture(Stream *stream, InstanceManager *manager);
|
|
||||||
|
|
||||||
|
|
||||||
inline Spectrum getValue(const Intersection &its) const {
|
|
||||||
return Spectrum(m_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Spectrum getAverage() const {
|
|
||||||
return Spectrum(m_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Spectrum getMaximum() const {
|
|
||||||
return Spectrum(m_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string toString() const {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "ConstantFloatTexture[value=" << m_value << "]";
|
|
||||||
return oss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool usesRayDifferentials() const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Shader *createShader(Renderer *renderer) const;
|
|
||||||
|
|
||||||
void serialize(Stream *stream, InstanceManager *manager) const;
|
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
|
||||||
protected:
|
|
||||||
Float m_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
MTS_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif /* __CONST_TEXTURE_H */
|
|
|
@ -20,6 +20,7 @@
|
||||||
#define __TEXTURE_H
|
#define __TEXTURE_H
|
||||||
|
|
||||||
#include <mitsuba/core/cobject.h>
|
#include <mitsuba/core/cobject.h>
|
||||||
|
#include <mitsuba/core/properties.h>
|
||||||
#include <mitsuba/render/shader.h>
|
#include <mitsuba/render/shader.h>
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
@ -85,6 +86,133 @@ protected:
|
||||||
Vector2 m_uvScale;
|
Vector2 m_uvScale;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ============================================================ */
|
||||||
|
/* Some vary basic texture definitions */
|
||||||
|
/* ============================================================ */
|
||||||
|
|
||||||
|
class MTS_EXPORT_RENDER ConstantSpectrumTexture : public Texture {
|
||||||
|
public:
|
||||||
|
inline ConstantSpectrumTexture(const Spectrum &value)
|
||||||
|
: Texture(Properties()), m_value(value) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstantSpectrumTexture(Stream *stream, InstanceManager *manager);
|
||||||
|
|
||||||
|
inline Spectrum getValue(const Intersection &its) const {
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Spectrum getAverage() const {
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Spectrum getMaximum() const {
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string toString() const {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "ConstantSpectrumTexture[value=" << m_value.toString() << "]";
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool usesRayDifferentials() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader *createShader(Renderer *renderer) const;
|
||||||
|
|
||||||
|
void serialize(Stream *stream, InstanceManager *manager) const;
|
||||||
|
|
||||||
|
MTS_DECLARE_CLASS()
|
||||||
|
protected:
|
||||||
|
Spectrum m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MTS_EXPORT_RENDER ConstantFloatTexture : public Texture {
|
||||||
|
public:
|
||||||
|
inline ConstantFloatTexture(const Float &value)
|
||||||
|
: Texture(Properties()), m_value(value) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstantFloatTexture(Stream *stream, InstanceManager *manager);
|
||||||
|
|
||||||
|
|
||||||
|
inline Spectrum getValue(const Intersection &its) const {
|
||||||
|
return Spectrum(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Spectrum getAverage() const {
|
||||||
|
return Spectrum(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Spectrum getMaximum() const {
|
||||||
|
return Spectrum(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string toString() const {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "ConstantFloatTexture[value=" << m_value << "]";
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool usesRayDifferentials() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader *createShader(Renderer *renderer) const;
|
||||||
|
|
||||||
|
void serialize(Stream *stream, InstanceManager *manager) const;
|
||||||
|
|
||||||
|
MTS_DECLARE_CLASS()
|
||||||
|
protected:
|
||||||
|
Float m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MTS_EXPORT_RENDER ScaleTexture : public Texture {
|
||||||
|
public:
|
||||||
|
inline ScaleTexture(const Texture *nested, const Float &scale)
|
||||||
|
: Texture(Properties()), m_nested(nested), m_scale(scale) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ScaleTexture(Stream *stream, InstanceManager *manager);
|
||||||
|
|
||||||
|
|
||||||
|
inline Spectrum getValue(const Intersection &its) const {
|
||||||
|
return m_nested->getValue(its) * m_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Spectrum getAverage() const {
|
||||||
|
return m_nested->getAverage() * m_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Spectrum getMaximum() const {
|
||||||
|
return m_nested->getMaximum() * m_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string toString() const {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "ScaleTexture[" << endl
|
||||||
|
<< " nested = " << indent(m_nested->toString()) << "," << endl
|
||||||
|
<< " scale = " << m_scale << endl
|
||||||
|
<< "]";
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool usesRayDifferentials() const {
|
||||||
|
return m_nested->usesRayDifferentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader *createShader(Renderer *renderer) const;
|
||||||
|
|
||||||
|
void serialize(Stream *stream, InstanceManager *manager) const;
|
||||||
|
|
||||||
|
MTS_DECLARE_CLASS()
|
||||||
|
protected:
|
||||||
|
ref<const Texture> m_nested;
|
||||||
|
Float m_scale;
|
||||||
|
};
|
||||||
|
|
||||||
MTS_NAMESPACE_END
|
MTS_NAMESPACE_END
|
||||||
|
|
||||||
#endif /* __TEXTURE_H */
|
#endif /* __TEXTURE_H */
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/bsdf.h>
|
#include <mitsuba/render/bsdf.h>
|
||||||
#include <mitsuba/render/consttexture.h>
|
#include <mitsuba/render/texture.h>
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/bsdf.h>
|
#include <mitsuba/render/bsdf.h>
|
||||||
#include <mitsuba/render/consttexture.h>
|
#include <mitsuba/render/texture.h>
|
||||||
#include <mitsuba/core/fresolver.h>
|
#include <mitsuba/core/fresolver.h>
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
@ -180,6 +180,13 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void configure() {
|
||||||
|
BSDF::configure();
|
||||||
|
/* Verify the input parameter and fix them if necessary */
|
||||||
|
m_specularReflectance = ensureEnergyConservation(
|
||||||
|
m_specularReflectance, "specularReflectance", 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
/// Reflection in local coordinates
|
/// Reflection in local coordinates
|
||||||
inline Vector reflect(const Vector &wi) const {
|
inline Vector reflect(const Vector &wi) const {
|
||||||
return Vector(-wi.x, -wi.y, wi.z);
|
return Vector(-wi.x, -wi.y, wi.z);
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/bsdf.h>
|
#include <mitsuba/render/bsdf.h>
|
||||||
#include <mitsuba/render/consttexture.h>
|
#include <mitsuba/render/texture.h>
|
||||||
#include "ior.h"
|
#include "ior.h"
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
@ -186,6 +186,15 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void configure() {
|
||||||
|
BSDF::configure();
|
||||||
|
/* Verify the input parameter and fix them if necessary */
|
||||||
|
m_specularReflectance = ensureEnergyConservation(
|
||||||
|
m_specularReflectance, "specularReflectance", 1.0f);
|
||||||
|
m_specularTransmittance = ensureEnergyConservation(
|
||||||
|
m_specularTransmittance, "specularTransmittance", 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
/// Reflection in local coordinates
|
/// Reflection in local coordinates
|
||||||
inline Vector reflect(const Vector &wi) const {
|
inline Vector reflect(const Vector &wi) const {
|
||||||
return Vector(-wi.x, -wi.y, wi.z);
|
return Vector(-wi.x, -wi.y, wi.z);
|
||||||
|
|
|
@ -17,12 +17,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/bsdf.h>
|
#include <mitsuba/render/bsdf.h>
|
||||||
#include <mitsuba/render/consttexture.h>
|
#include <mitsuba/render/texture.h>
|
||||||
#include <mitsuba/hw/renderer.h>
|
#include <mitsuba/hw/renderer.h>
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
|
||||||
/*! \plugin{difftrans}{Diffuse transmitter}
|
/*! \plugin{difftrans}{Diffuse transmitter}
|
||||||
*
|
*
|
||||||
* \parameters{
|
* \parameters{
|
||||||
|
@ -42,7 +41,6 @@ MTS_NAMESPACE_BEGIN
|
||||||
* plugin.} with a surface reflection model to describe translucent substances
|
* plugin.} with a surface reflection model to describe translucent substances
|
||||||
* that have internal multiple scattering processes (e.g. plant leaves).
|
* that have internal multiple scattering processes (e.g. plant leaves).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class DiffuseTransmitter : public BSDF {
|
class DiffuseTransmitter : public BSDF {
|
||||||
public:
|
public:
|
||||||
DiffuseTransmitter(const Properties &props)
|
DiffuseTransmitter(const Properties &props)
|
||||||
|
@ -65,6 +63,12 @@ public:
|
||||||
|
|
||||||
virtual ~DiffuseTransmitter() { }
|
virtual ~DiffuseTransmitter() { }
|
||||||
|
|
||||||
|
void configure() {
|
||||||
|
BSDF::configure();
|
||||||
|
/* Verify the input parameter and fix them if necessary */
|
||||||
|
m_transmittance = ensureEnergyConservation(m_transmittance, "transmittance", 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
Spectrum eval(const BSDFQueryRecord &bRec, EMeasure measure) const {
|
Spectrum eval(const BSDFQueryRecord &bRec, EMeasure measure) const {
|
||||||
if (!(bRec.typeMask & EDiffuseTransmission) || measure != ESolidAngle
|
if (!(bRec.typeMask & EDiffuseTransmission) || measure != ESolidAngle
|
||||||
|| Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0)
|
|| Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0)
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/bsdf.h>
|
#include <mitsuba/render/bsdf.h>
|
||||||
#include <mitsuba/render/consttexture.h>
|
#include <mitsuba/render/texture.h>
|
||||||
#include <mitsuba/core/properties.h>
|
|
||||||
#include <mitsuba/hw/renderer.h>
|
#include <mitsuba/hw/renderer.h>
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
@ -87,6 +86,16 @@ public:
|
||||||
|
|
||||||
virtual ~SmoothDiffuse() { }
|
virtual ~SmoothDiffuse() { }
|
||||||
|
|
||||||
|
void configure() {
|
||||||
|
BSDF::configure();
|
||||||
|
/* Verify the input parameter and fix them if necessary */
|
||||||
|
m_reflectance = ensureEnergyConservation(m_reflectance, "reflectance", 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Spectrum getDiffuseReflectance(const Intersection &its) const {
|
||||||
|
return m_reflectance->getValue(its);
|
||||||
|
}
|
||||||
|
|
||||||
Spectrum eval(const BSDFQueryRecord &bRec, EMeasure measure) const {
|
Spectrum eval(const BSDFQueryRecord &bRec, EMeasure measure) const {
|
||||||
if (!(bRec.typeMask & EDiffuseReflection) || measure != ESolidAngle
|
if (!(bRec.typeMask & EDiffuseReflection) || measure != ESolidAngle
|
||||||
|| Frame::cosTheta(bRec.wi) <= 0
|
|| Frame::cosTheta(bRec.wi) <= 0
|
||||||
|
@ -147,6 +156,7 @@ public:
|
||||||
std::string toString() const {
|
std::string toString() const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "SmoothDiffuse[" << endl
|
oss << "SmoothDiffuse[" << endl
|
||||||
|
<< " name = \"" << getName() << "\"," << endl
|
||||||
<< " reflectance = " << indent(m_reflectance->toString()) << endl
|
<< " reflectance = " << indent(m_reflectance->toString()) << endl
|
||||||
<< "]";
|
<< "]";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
|
|
|
@ -106,7 +106,7 @@ public:
|
||||||
|
|
||||||
case EPhong: {
|
case EPhong: {
|
||||||
/* Phong distribution function */
|
/* Phong distribution function */
|
||||||
result = (alphaU + 1) * INV_TWOPI
|
result = (alphaU + 2) * INV_TWOPI
|
||||||
* std::pow(Frame::cosTheta(m), alphaU);
|
* std::pow(Frame::cosTheta(m), alphaU);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -315,20 +315,8 @@ public:
|
||||||
* \param alpha The surface roughness
|
* \param alpha The surface roughness
|
||||||
*/
|
*/
|
||||||
Float G(const Vector &wi, const Vector &wo, const Vector &m, Float alphaU, Float alphaV) const {
|
Float G(const Vector &wi, const Vector &wo, const Vector &m, Float alphaU, Float alphaV) const {
|
||||||
if (EXPECT_TAKEN(m_type != EAshikhminShirley)) {
|
Float alpha = std::max(alphaU, alphaV);
|
||||||
return smithG1(wi, m, alphaU) * smithG1(wo, m, alphaV);
|
return smithG1(wi, m, alpha) * smithG1(wo, m, alpha);
|
||||||
} else {
|
|
||||||
/* Infinite groove shadowing/masking */
|
|
||||||
const Float nDotM = std::abs(Frame::cosTheta(m)),
|
|
||||||
nDotWo = std::abs(Frame::cosTheta(wo)),
|
|
||||||
nDotWi = std::abs(Frame::cosTheta(wi)),
|
|
||||||
woDotM = absDot(wo, m),
|
|
||||||
wiDotM = absDot(wi, m);
|
|
||||||
|
|
||||||
return std::max((Float) 0, std::min((Float) 1,
|
|
||||||
std::min(2 * nDotM * nDotWo / woDotM,
|
|
||||||
2 * nDotM * nDotWi / wiDotM)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString() const {
|
std::string toString() const {
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
|
|
||||||
m_exponent = props.getFloat("exponent", 10.0f);
|
m_exponent = props.getFloat("exponent", 10.0f);
|
||||||
|
|
||||||
m_verifyEnergyConservation = props.getBoolean("verifyEnergyConservation", true);
|
m_ensureEnergyConservation = props.getBoolean("ensureEnergyConservation", true);
|
||||||
m_specularSamplingWeight = props.getFloat("specularSamplingWeight", -1);
|
m_specularSamplingWeight = props.getFloat("specularSamplingWeight", -1);
|
||||||
|
|
||||||
m_componentCount = 2;
|
m_componentCount = 2;
|
||||||
|
@ -78,14 +78,14 @@ public:
|
||||||
|
|
||||||
void configure() {
|
void configure() {
|
||||||
BSDF::configure();
|
BSDF::configure();
|
||||||
if (m_verifyEnergyConservation && (m_kd * m_diffuseReflectance->getMaximum().max()
|
if (m_ensureEnergyConservation && (m_kd * m_diffuseReflectance->getMaximum().max()
|
||||||
+ m_ks * m_specularReflectance->getMaximum().max() > 1.0f)) {
|
+ m_ks * m_specularReflectance->getMaximum().max() > 1.0f)) {
|
||||||
Log(EWarn, "Material \"%s\": Energy conservation is potentially violated!", getName().c_str());
|
Log(EWarn, "Material \"%s\": Energy conservation is potentially violated!", getName().c_str());
|
||||||
Log(EWarn, "Max. diffuse reflectance = %f * %f = %f", m_kd, m_diffuseReflectance->getMaximum().max(), m_kd*m_diffuseReflectance->getMaximum().max());
|
Log(EWarn, "Max. diffuse reflectance = %f * %f = %f", m_kd, m_diffuseReflectance->getMaximum().max(), m_kd*m_diffuseReflectance->getMaximum().max());
|
||||||
Log(EWarn, "Max. specular reflectance = %f * %f = %f", m_ks, m_specularReflectance->getMaximum().max(), m_ks*m_specularReflectance->getMaximum().max());
|
Log(EWarn, "Max. specular reflectance = %f * %f = %f", m_ks, m_specularReflectance->getMaximum().max(), m_ks*m_specularReflectance->getMaximum().max());
|
||||||
Float normalization = 1/(m_kd * m_diffuseReflectance->getMaximum().max() + m_ks * m_specularReflectance->getMaximum().max());
|
Float normalization = 1/(m_kd * m_diffuseReflectance->getMaximum().max() + m_ks * m_specularReflectance->getMaximum().max());
|
||||||
Log(EWarn, "Reducing the albedo to %.1f%% of the original value to be on the safe side. "
|
Log(EWarn, "Reducing the albedo to %.1f%% of the original value to be on the safe side. "
|
||||||
"Specify verifyEnergyConservation=false to prevent this.", normalization * 100);
|
"Specify ensureEnergyConservation=false to prevent this.", normalization * 100);
|
||||||
m_kd *= normalization; m_ks *= normalization;
|
m_kd *= normalization; m_ks *= normalization;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ private:
|
||||||
Float m_kd, m_ks;
|
Float m_kd, m_ks;
|
||||||
Float m_specularSamplingWeight;
|
Float m_specularSamplingWeight;
|
||||||
Float m_diffuseSamplingWeight;
|
Float m_diffuseSamplingWeight;
|
||||||
bool m_verifyEnergyConservation;
|
bool m_ensureEnergyConservation;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ================ Hardware shader implementation ================
|
// ================ Hardware shader implementation ================
|
||||||
|
|
|
@ -18,8 +18,9 @@
|
||||||
|
|
||||||
#include <mitsuba/render/bsdf.h>
|
#include <mitsuba/render/bsdf.h>
|
||||||
#include <mitsuba/render/sampler.h>
|
#include <mitsuba/render/sampler.h>
|
||||||
#include <mitsuba/render/consttexture.h>
|
#include <mitsuba/render/texture.h>
|
||||||
#include "microfacet.h"
|
#include "microfacet.h"
|
||||||
|
#include "ior.h"
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
@ -123,8 +124,8 @@ MTS_NAMESPACE_BEGIN
|
||||||
* \begin{xml}[caption=A texture can be attached to the roughness parameter, label=lst:roughdielectric-textured]
|
* \begin{xml}[caption=A texture can be attached to the roughness parameter, label=lst:roughdielectric-textured]
|
||||||
* <bsdf type="roughdielectric">
|
* <bsdf type="roughdielectric">
|
||||||
* <string name="distribution" value="beckmann"/>
|
* <string name="distribution" value="beckmann"/>
|
||||||
* <float name="intIOR" value="1.5046"/>
|
* <string name="intIOR" value="bk7"/>
|
||||||
* <float name="extIOR" value="1.0"/>
|
* <string name="extIOR" value="air"/>
|
||||||
*
|
*
|
||||||
* <texture name="alpha" type="bitmap">
|
* <texture name="alpha" type="bitmap">
|
||||||
* <string name="filename" value="roughness.exr"/>
|
* <string name="filename" value="roughness.exr"/>
|
||||||
|
@ -141,8 +142,11 @@ public:
|
||||||
m_specularTransmittance = new ConstantSpectrumTexture(
|
m_specularTransmittance = new ConstantSpectrumTexture(
|
||||||
props.getSpectrum("specularTransmittance", Spectrum(1.0f)));
|
props.getSpectrum("specularTransmittance", Spectrum(1.0f)));
|
||||||
|
|
||||||
m_intIOR = props.getFloat("intIOR", 1.5046f);
|
/* Specifies the internal index of refraction at the interface */
|
||||||
m_extIOR = props.getFloat("extIOR", 1.0f);
|
m_intIOR = lookupIOR(props, "intIOR", "bk7");
|
||||||
|
|
||||||
|
/* Specifies the external index of refraction at the interface */
|
||||||
|
m_extIOR = lookupIOR(props, "extIOR", "air");
|
||||||
|
|
||||||
if (m_intIOR < 0 || m_extIOR < 0 || m_intIOR == m_extIOR)
|
if (m_intIOR < 0 || m_extIOR < 0 || m_intIOR == m_extIOR)
|
||||||
Log(EError, "The interior and exterior indices of "
|
Log(EError, "The interior and exterior indices of "
|
||||||
|
@ -208,6 +212,12 @@ public:
|
||||||
m_components.push_back(
|
m_components.push_back(
|
||||||
EGlossyTransmission | EFrontSide | EBackSide | ECanUseSampler | extraFlags);
|
EGlossyTransmission | EFrontSide | EBackSide | ECanUseSampler | extraFlags);
|
||||||
|
|
||||||
|
/* Verify the input parameter and fix them if necessary */
|
||||||
|
m_specularReflectance = ensureEnergyConservation(
|
||||||
|
m_specularReflectance, "specularReflectance", 1.0f);
|
||||||
|
m_specularTransmittance = ensureEnergyConservation(
|
||||||
|
m_specularTransmittance, "specularTransmittance", 1.0f);
|
||||||
|
|
||||||
BSDF::configure();
|
BSDF::configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +313,8 @@ public:
|
||||||
} else {
|
} else {
|
||||||
/* Calculate the total amount of transmission */
|
/* Calculate the total amount of transmission */
|
||||||
Float sqrtDenom = etaI * dot(bRec.wi, H) + etaT * dot(bRec.wo, H);
|
Float sqrtDenom = etaI * dot(bRec.wi, H) + etaT * dot(bRec.wo, H);
|
||||||
Float value = ((1 - F) * D * G * etaT * etaT * dot(bRec.wi, H)*dot(bRec.wo, H)) /
|
Float value = ((1 - F) * D * G * etaT * etaT
|
||||||
|
* dot(bRec.wi, H) * dot(bRec.wo, H)) /
|
||||||
(Frame::cosTheta(bRec.wi) * sqrtDenom * sqrtDenom);
|
(Frame::cosTheta(bRec.wi) * sqrtDenom * sqrtDenom);
|
||||||
|
|
||||||
/* Missing term in the original paper: account for the solid angle
|
/* Missing term in the original paper: account for the solid angle
|
||||||
|
@ -380,6 +391,7 @@ public:
|
||||||
std::abs(Frame::cosTheta(bRec.wi))));
|
std::abs(Frame::cosTheta(bRec.wi))));
|
||||||
alphaU *= factor; alphaV *= factor;
|
alphaU *= factor; alphaV *= factor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Microsurface normal sampling density */
|
/* Microsurface normal sampling density */
|
||||||
Float prob = m_distribution.pdf(H, alphaU, alphaV);
|
Float prob = m_distribution.pdf(H, alphaU, alphaV);
|
||||||
|
|
||||||
|
@ -512,7 +524,8 @@ public:
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
result = m_specularTransmittance->getValue(bRec.its)
|
result = m_specularTransmittance->getValue(bRec.its)
|
||||||
* ((bRec.quantity == ERadiance) ? ((etaI*etaI) / (etaT*etaT)) : (Float) 1);
|
* ((bRec.quantity == ERadiance) ?
|
||||||
|
((etaI*etaI) / (etaT*etaT)) : (Float) 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Float numerator = m_distribution.eval(m, alphaU, alphaV)
|
Float numerator = m_distribution.eval(m, alphaU, alphaV)
|
||||||
|
@ -603,7 +616,8 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Sample M, the microsurface normal */
|
/* Sample M, the microsurface normal */
|
||||||
const Normal m = m_distribution.sample(sample, sampleAlphaU, sampleAlphaV);
|
const Normal m = m_distribution.sample(sample,
|
||||||
|
sampleAlphaU, sampleAlphaV);
|
||||||
|
|
||||||
if (sampleExactFresnelTerm) {
|
if (sampleExactFresnelTerm) {
|
||||||
Float sampleF = fresnel(dot(bRec.wi, m), m_extIOR, m_intIOR);
|
Float sampleF = fresnel(dot(bRec.wi, m), m_extIOR, m_intIOR);
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/bsdf.h>
|
#include <mitsuba/render/bsdf.h>
|
||||||
#include <mitsuba/render/consttexture.h>
|
#include <mitsuba/render/texture.h>
|
||||||
#include <mitsuba/hw/gpuprogram.h>
|
#include <mitsuba/hw/gpuprogram.h>
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
|
@ -72,7 +72,7 @@ public:
|
||||||
Log(EError, "Specified an invalid model type \"%s\", must be "
|
Log(EError, "Specified an invalid model type \"%s\", must be "
|
||||||
"\"ward\", \"ward-duer\", or \"balanced\"!", type.c_str());
|
"\"ward\", \"ward-duer\", or \"balanced\"!", type.c_str());
|
||||||
|
|
||||||
m_verifyEnergyConservation = props.getBoolean("verifyEnergyConservation", true);
|
m_ensureEnergyConservation = props.getBoolean("ensureEnergyConservation", true);
|
||||||
m_specularSamplingWeight = props.getFloat("specularSamplingWeight", -1);
|
m_specularSamplingWeight = props.getFloat("specularSamplingWeight", -1);
|
||||||
|
|
||||||
m_alphaX = props.getFloat("alphaX", .1f);
|
m_alphaX = props.getFloat("alphaX", .1f);
|
||||||
|
@ -116,14 +116,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void configure() {
|
void configure() {
|
||||||
if (m_verifyEnergyConservation && (m_kd * m_diffuseReflectance->getMaximum().max()
|
if (m_ensureEnergyConservation && (m_kd * m_diffuseReflectance->getMaximum().max()
|
||||||
+ m_ks * m_specularReflectance->getMaximum().max() > 1.0f)) {
|
+ m_ks * m_specularReflectance->getMaximum().max() > 1.0f)) {
|
||||||
Log(EWarn, "Material \"%s\": Energy conservation is potentially violated!", getName().c_str());
|
Log(EWarn, "Material \"%s\": Energy conservation is potentially violated!", getName().c_str());
|
||||||
Log(EWarn, "Max. diffuse reflectance = %f * %f = %f", m_kd, m_diffuseReflectance->getMaximum().max(), m_kd*m_diffuseReflectance->getMaximum().max());
|
Log(EWarn, "Max. diffuse reflectance = %f * %f = %f", m_kd, m_diffuseReflectance->getMaximum().max(), m_kd*m_diffuseReflectance->getMaximum().max());
|
||||||
Log(EWarn, "Max. specular reflectance = %f * %f = %f", m_ks, m_specularReflectance->getMaximum().max(), m_ks*m_specularReflectance->getMaximum().max());
|
Log(EWarn, "Max. specular reflectance = %f * %f = %f", m_ks, m_specularReflectance->getMaximum().max(), m_ks*m_specularReflectance->getMaximum().max());
|
||||||
Float normalization = 1/(m_kd * m_diffuseReflectance->getMaximum().max() + m_ks * m_specularReflectance->getMaximum().max());
|
Float normalization = 1/(m_kd * m_diffuseReflectance->getMaximum().max() + m_ks * m_specularReflectance->getMaximum().max());
|
||||||
Log(EWarn, "Reducing the albedo to %.1f%% of the original value to be on the safe side. "
|
Log(EWarn, "Reducing the albedo to %.1f%% of the original value to be on the safe side. "
|
||||||
"Specify verifyEnergyConservation=false to prevent this.", normalization * 100);
|
"Specify ensureEnergyConservation=false to prevent this.", normalization * 100);
|
||||||
m_kd *= normalization; m_ks *= normalization;
|
m_kd *= normalization; m_ks *= normalization;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ private:
|
||||||
Float m_kd, m_ks;
|
Float m_kd, m_ks;
|
||||||
Float m_specularSamplingWeight;
|
Float m_specularSamplingWeight;
|
||||||
Float m_diffuseSamplingWeight;
|
Float m_diffuseSamplingWeight;
|
||||||
bool m_verifyEnergyConservation;
|
bool m_ensureEnergyConservation;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ================ Hardware shader implementation ================
|
// ================ Hardware shader implementation ================
|
||||||
|
|
|
@ -23,11 +23,17 @@ MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
BSDF::BSDF(const Properties &props)
|
BSDF::BSDF(const Properties &props)
|
||||||
: ConfigurableObject(props), m_name(props.getID()) {
|
: ConfigurableObject(props), m_name(props.getID()) {
|
||||||
|
/* By default, verify whether energy conservation holds
|
||||||
|
for the user-specified parameter values. This step
|
||||||
|
is completely up to the particular BSDF implementations */
|
||||||
|
m_ensureEnergyConservation = props.getBoolean(
|
||||||
|
"ensureEnergyConservation", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
BSDF::BSDF(Stream *stream, InstanceManager *manager)
|
BSDF::BSDF(Stream *stream, InstanceManager *manager)
|
||||||
: ConfigurableObject(stream, manager) {
|
: ConfigurableObject(stream, manager) {
|
||||||
m_name = stream->readString();
|
m_name = stream->readString();
|
||||||
|
m_ensureEnergyConservation = stream->readBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
BSDF::~BSDF() { }
|
BSDF::~BSDF() { }
|
||||||
|
@ -35,6 +41,7 @@ BSDF::~BSDF() { }
|
||||||
void BSDF::serialize(Stream *stream, InstanceManager *manager) const {
|
void BSDF::serialize(Stream *stream, InstanceManager *manager) const {
|
||||||
ConfigurableObject::serialize(stream, manager);
|
ConfigurableObject::serialize(stream, manager);
|
||||||
stream->writeString(m_name);
|
stream->writeString(m_name);
|
||||||
|
stream->writeBool(m_ensureEnergyConservation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSDF::setParent(ConfigurableObject *parent) {
|
void BSDF::setParent(ConfigurableObject *parent) {
|
||||||
|
@ -58,6 +65,28 @@ Spectrum BSDF::getDiffuseReflectance(const Intersection &its) const {
|
||||||
return eval(bRec) * M_PI;
|
return eval(bRec) * M_PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture *BSDF::ensureEnergyConservation(Texture *texture,
|
||||||
|
const std::string ¶mName, Float max) const {
|
||||||
|
if (!m_ensureEnergyConservation)
|
||||||
|
return texture;
|
||||||
|
|
||||||
|
Float actualMax = texture->getMaximum().max();
|
||||||
|
if (actualMax > max) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
Float scale = 0.99f * (max / actualMax);
|
||||||
|
oss << "The BSDF" << endl << toString() << endl
|
||||||
|
<< "violates energy conservation! The parameter \"" << paramName << "\" "
|
||||||
|
<< "has a component-wise maximum of "<< actualMax << " (which is > " << max << "!) "
|
||||||
|
<< "and will therefore be scaled by " << scale << " to prevent "
|
||||||
|
<< "issues. Specify the parameter ensureEnergyConservation=false "
|
||||||
|
<< "to the BSDF to prevent this from happening.";
|
||||||
|
Log(EWarn, "%s", oss.str().c_str());
|
||||||
|
return new ScaleTexture(texture, scale);
|
||||||
|
}
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static std::string typeMaskToString(unsigned int typeMask) {
|
static std::string typeMaskToString(unsigned int typeMask) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "{ ";
|
oss << "{ ";
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/consttexture.h>
|
#include <mitsuba/render/texture.h>
|
||||||
#include <mitsuba/hw/gpuprogram.h>
|
#include <mitsuba/hw/gpuprogram.h>
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
@ -102,6 +102,18 @@ void ConstantFloatTexture::serialize(Stream *stream, InstanceManager *manager) c
|
||||||
stream->writeFloat(m_value);
|
stream->writeFloat(m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScaleTexture::ScaleTexture(Stream *stream, InstanceManager *manager)
|
||||||
|
: Texture(stream, manager) {
|
||||||
|
m_nested = static_cast<Texture *>(manager->getInstance(stream));
|
||||||
|
m_scale = stream->readFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleTexture::serialize(Stream *stream, InstanceManager *manager) const {
|
||||||
|
Texture::serialize(stream, manager);
|
||||||
|
manager->serialize(stream, m_nested.get());
|
||||||
|
stream->writeFloat(m_scale);
|
||||||
|
}
|
||||||
|
|
||||||
class ConstantSpectrumTextureShader : public Shader {
|
class ConstantSpectrumTextureShader : public Shader {
|
||||||
public:
|
public:
|
||||||
ConstantSpectrumTextureShader(Renderer *renderer, const Spectrum &value)
|
ConstantSpectrumTextureShader(Renderer *renderer, const Spectrum &value)
|
||||||
|
@ -160,6 +172,50 @@ private:
|
||||||
Float m_value;
|
Float m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ScaleTextureShader : public Shader {
|
||||||
|
public:
|
||||||
|
ScaleTextureShader(Renderer *renderer, const Texture *nested, const Float &scale)
|
||||||
|
: Shader(renderer, ETextureShader), m_nested(nested), m_scale(scale) {
|
||||||
|
m_nestedShader = renderer->registerShaderForResource(m_nested.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isComplete() const {
|
||||||
|
return m_nestedShader.get() != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup(Renderer *renderer) {
|
||||||
|
renderer->unregisterShaderForResource(m_nested.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void putDependencies(std::vector<Shader *> &deps) {
|
||||||
|
deps.push_back(m_nestedShader.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateCode(std::ostringstream &oss,
|
||||||
|
const std::string &evalName,
|
||||||
|
const std::vector<std::string> &depNames) const {
|
||||||
|
oss << "uniform float " << evalName << "_scale;" << endl
|
||||||
|
<< endl
|
||||||
|
<< "vec3 " << evalName << "(vec2 uv) {" << endl
|
||||||
|
<< " return " << depNames[0] << "(uv) * " << evalName << "_scale;" << endl
|
||||||
|
<< "}" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resolve(const GPUProgram *program, const std::string &evalName, std::vector<int> ¶meterIDs) const {
|
||||||
|
parameterIDs.push_back(program->getParameterID(evalName + "_scale"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind(GPUProgram *program, const std::vector<int> ¶meterIDs, int &nestedUnitOffset) const {
|
||||||
|
program->setParameter(parameterIDs[0], m_scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
MTS_DECLARE_CLASS()
|
||||||
|
private:
|
||||||
|
ref<const Texture> m_nested;
|
||||||
|
ref<Shader> m_nestedShader;
|
||||||
|
Float m_scale;
|
||||||
|
};
|
||||||
|
|
||||||
Shader *ConstantSpectrumTexture::createShader(Renderer *renderer) const {
|
Shader *ConstantSpectrumTexture::createShader(Renderer *renderer) const {
|
||||||
return new ConstantSpectrumTextureShader(renderer, m_value);
|
return new ConstantSpectrumTextureShader(renderer, m_value);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +224,9 @@ Shader *ConstantFloatTexture::createShader(Renderer *renderer) const {
|
||||||
return new ConstantFloatTextureShader(renderer, m_value);
|
return new ConstantFloatTextureShader(renderer, m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shader *ScaleTexture::createShader(Renderer *renderer) const {
|
||||||
|
return new ScaleTextureShader(renderer, m_nested.get(), m_scale);
|
||||||
|
}
|
||||||
|
|
||||||
MTS_IMPLEMENT_CLASS(Texture, true, ConfigurableObject)
|
MTS_IMPLEMENT_CLASS(Texture, true, ConfigurableObject)
|
||||||
MTS_IMPLEMENT_CLASS(Texture2D, true, Texture)
|
MTS_IMPLEMENT_CLASS(Texture2D, true, Texture)
|
||||||
|
@ -176,4 +234,6 @@ MTS_IMPLEMENT_CLASS_S(ConstantSpectrumTexture, false, Texture)
|
||||||
MTS_IMPLEMENT_CLASS(ConstantSpectrumTextureShader, false, Shader)
|
MTS_IMPLEMENT_CLASS(ConstantSpectrumTextureShader, false, Shader)
|
||||||
MTS_IMPLEMENT_CLASS_S(ConstantFloatTexture, false, Texture)
|
MTS_IMPLEMENT_CLASS_S(ConstantFloatTexture, false, Texture)
|
||||||
MTS_IMPLEMENT_CLASS(ConstantFloatTextureShader, false, Shader)
|
MTS_IMPLEMENT_CLASS(ConstantFloatTextureShader, false, Shader)
|
||||||
|
MTS_IMPLEMENT_CLASS_S(ScaleTexture, false, Texture)
|
||||||
|
MTS_IMPLEMENT_CLASS(ScaleTextureShader, false, Shader)
|
||||||
MTS_NAMESPACE_END
|
MTS_NAMESPACE_END
|
||||||
|
|
|
@ -390,7 +390,7 @@ public:
|
||||||
// into doing correct texture filtering across the u=0 to u=1 seam.
|
// into doing correct texture filtering across the u=0 to u=1 seam.
|
||||||
<< " if (u < 0.1)" << endl
|
<< " if (u < 0.1)" << endl
|
||||||
<< " return texture2D(" << evalName << "_texture, vec2(u+1.0, v)).rgb * " << evalName << "_intensityScale;" << endl
|
<< " return texture2D(" << evalName << "_texture, vec2(u+1.0, v)).rgb * " << evalName << "_intensityScale;" << endl
|
||||||
<< " else"
|
<< " else" << endl
|
||||||
<< " return texture2D(" << evalName << "_texture, vec2(u, v)).rgb * " << evalName << "_intensityScale;" << endl
|
<< " return texture2D(" << evalName << "_texture, vec2(u, v)).rgb * " << evalName << "_intensityScale;" << endl
|
||||||
<< "}" << endl;
|
<< "}" << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/scene.h>
|
#include <mitsuba/render/scene.h>
|
||||||
#include <mitsuba/render/consttexture.h>
|
#include <mitsuba/render/texture.h>
|
||||||
#include <mitsuba/hw/gpuprogram.h>
|
#include <mitsuba/hw/gpuprogram.h>
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
Loading…
Reference in New Issue