fixed some inconsistencies in the HG phase function, clarified conventions in the documentation

metadata
Wenzel Jakob 2010-09-17 14:45:23 +02:00
parent 606528e89c
commit a295b0ecd8
4 changed files with 16 additions and 14 deletions

View File

@ -74,7 +74,10 @@ public:
Float miWeight; Float miWeight;
}; };
/** \brief Abstract phase function /** \brief Abstract phase function.
*
* The convention used here is that the incident and exitant
* direction arguments point away from the scattering event (similar to BSDFs).
*/ */
class MTS_EXPORT_RENDER PhaseFunction : public ConfigurableObject { class MTS_EXPORT_RENDER PhaseFunction : public ConfigurableObject {
public: public:
@ -83,7 +86,7 @@ public:
EDelta EDelta
}; };
/// Evaluate the phase function for a pair of directions (wi, wo) /// Evaluate the phase function for an outward-pointing pair of directions (wi, wo)
virtual Spectrum f(const MediumSamplingRecord &mRec, const Vector &wi, const Vector &wo) const = 0; virtual Spectrum f(const MediumSamplingRecord &mRec, const Vector &wi, const Vector &wo) const = 0;
/** /**

View File

@ -596,8 +596,8 @@ Spectrum FlakePhaseFunction::sample(const MediumSamplingRecord &mRec, const Vect
Vector wo = sphericalDirection(sample.x, sample.y); Vector wo = sphericalDirection(sample.x, sample.y);
_wo = frame.toWorld(wo); _wo = frame.toWorld(wo);
return Spectrum(std::max((Float) 0, temp.eval(sample.x, sample.y))); // return Spectrum(std::max((Float) 0, temp.eval(sample.x, sample.y)));
// return f(mRec, _wi, _wo); return f(mRec, _wi, _wo);
#else #else
/* Uniform sampling */ /* Uniform sampling */
_wo = squareToSphere(_sample); _wo = squareToSphere(_sample);

View File

@ -56,19 +56,18 @@ public:
if (std::abs(m_g) < Epsilon) { if (std::abs(m_g) < Epsilon) {
cosTheta = 1 - 2*sample.x; cosTheta = 1 - 2*sample.x;
} else { } else {
Float sqrTerm = (1 - m_g * m_g) / Float sqrTerm = (1 - m_g * m_g) / (1 - m_g + 2 * m_g * sample.x);
(1 - m_g + 2 * m_g * sample.x);
cosTheta = (1 + m_g * m_g - sqrTerm * sqrTerm) / (2 * m_g); cosTheta = (1 + m_g * m_g - sqrTerm * sqrTerm) / (2 * m_g);
} }
Float sinTheta = std::sqrt(std::max((Float) 0, 1-cosTheta*cosTheta)); Float sinTheta = std::sqrt(std::max((Float) 0, 1.0f-cosTheta*cosTheta));
Float phi = 2*M_PI*sample.y, cosPhi = std::cos(phi), sinPhi = std::sin(phi); Float phi = 2*M_PI*sample.y, cosPhi = std::cos(phi), sinPhi = std::sin(phi);
Vector dir( Vector dir(
sinTheta * cosPhi, sinTheta * cosPhi,
sinTheta * sinPhi, sinTheta * sinPhi,
cosTheta); cosTheta);
wo = Frame(wi).toWorld(dir); wo = Frame(-wi).toWorld(dir);
sampledType = ENormal; sampledType = ENormal;
return Spectrum(1.0f); return Spectrum(1.0f);
@ -84,7 +83,7 @@ public:
Spectrum f(const MediumSamplingRecord &mRec, const Vector &wi, const Vector &wo) const { Spectrum f(const MediumSamplingRecord &mRec, const Vector &wi, const Vector &wo) const {
return Spectrum(1/(4*M_PI) * (1 - m_g*m_g) / return Spectrum(1/(4*M_PI) * (1 - m_g*m_g) /
std::pow(1.f + m_g*m_g - 2.f * m_g * dot(wi, wo), (Float) 1.5f)); std::pow(1.f + m_g*m_g - 2.f * m_g * dot(-wi, wo), (Float) 1.5f));
} }
std::string toString() const { std::string toString() const {

View File

@ -111,7 +111,7 @@ public:
ESampledType &sampledType, const Point2 &sample) const { ESampledType &sampledType, const Point2 &sample) const {
wo = squareToSphere(sample); wo = squareToSphere(sample);
sampledType = ENormal; sampledType = ENormal;
return Spectrum(1.0f); return f(mRec, wi, wo) / (4 * M_PI);
} }
Spectrum sample(const MediumSamplingRecord &mRec, const Vector &wi, Vector &wo, Spectrum sample(const MediumSamplingRecord &mRec, const Vector &wi, Vector &wo,
@ -119,17 +119,17 @@ public:
wo = squareToSphere(sample); wo = squareToSphere(sample);
sampledType = ENormal; sampledType = ENormal;
pdf = 1/(4 * (Float) M_PI); pdf = 1/(4 * (Float) M_PI);
return Spectrum(pdf); return f(mRec, wi, wo);
} }
Spectrum f(const MediumSamplingRecord &mRec, const Vector &wi, const Vector &wo) const { Spectrum f(const MediumSamplingRecord &mRec, const Vector &wi, const Vector &wo) const {
Frame frame(mRec.orientation);
if (mRec.orientation.length() == 0) if (mRec.orientation.length() == 0)
return Spectrum(m_kd / (4*M_PI)); return Spectrum(m_kd / (4*M_PI));
Vector orientation = normalize(mRec.orientation); Frame frame(normalize(mRec.orientation));
Vector reflectedLocal = frame.toLocal(wo); Vector reflectedLocal = frame.toLocal(wo);
reflectedLocal.z = -dot(wi, orientation);
reflectedLocal.z = -dot(wi, frame.n);
Float a = std::sqrt((1-reflectedLocal.z*reflectedLocal.z) / Float a = std::sqrt((1-reflectedLocal.z*reflectedLocal.z) /
(reflectedLocal.x*reflectedLocal.x + reflectedLocal.y*reflectedLocal.y)); (reflectedLocal.x*reflectedLocal.x + reflectedLocal.y*reflectedLocal.y));
reflectedLocal.y *= a; reflectedLocal.y *= a;