minor optimization (save a few square roots here and there)

metadata
Wenzel Jakob 2012-11-04 18:02:39 -05:00
parent 06d6b96c6e
commit f9d42ff3b2
3 changed files with 31 additions and 10 deletions

View File

@ -84,12 +84,24 @@ struct Frame {
return s * v.x + t * v.y + n * v.z; return s * v.x + t * v.y + n * v.z;
} }
/** \brief Assuming that the given direction is in the local coordinate
* system, return the squared cosine of the angle between the normal and v */
inline static Float cosTheta2(const Vector &v) {
return v.z * v.z;
}
/** \brief Assuming that the given direction is in the local coordinate /** \brief Assuming that the given direction is in the local coordinate
* system, return the cosine of the angle between the normal and v */ * system, return the cosine of the angle between the normal and v */
inline static Float cosTheta(const Vector &v) { inline static Float cosTheta(const Vector &v) {
return v.z; return v.z;
} }
/** \brief Assuming that the given direction is in the local coordinate
* system, return the squared sine of the angle between the normal and v */
inline static Float sinTheta2(const Vector &v) {
return 1.0f - v.z * v.z;
}
/** \brief Assuming that the given direction is in the local coordinate /** \brief Assuming that the given direction is in the local coordinate
* system, return the sine of the angle between the normal and v */ * system, return the sine of the angle between the normal and v */
inline static Float sinTheta(const Vector &v) { inline static Float sinTheta(const Vector &v) {
@ -109,9 +121,12 @@ struct Frame {
} }
/** \brief Assuming that the given direction is in the local coordinate /** \brief Assuming that the given direction is in the local coordinate
* system, return the squared sine of the angle between the normal and v */ * system, return the squared tangent of the angle between the normal and v */
inline static Float sinTheta2(const Vector &v) { inline static Float tanTheta2(const Vector &v) {
return 1.0f - v.z * v.z; Float temp = 1 - v.z*v.z;
if (temp <= 0.0f)
return 0.0f;
return temp / (v.z * v.z);
} }
/** \brief Assuming that the given direction is in the local coordinate /** \brief Assuming that the given direction is in the local coordinate

View File

@ -115,19 +115,21 @@ public:
switch (m_type) { switch (m_type) {
case EBeckmann: { case EBeckmann: {
/* Beckmann distribution function for Gaussian random surfaces */ /* Beckmann distribution function for Gaussian random surfaces */
const Float ex = Frame::tanTheta(m) / alphaU; const Float exponent = Frame::tanTheta2(m) / (alphaU*alphaU);
result = math::fastexp(-(ex*ex)) / (M_PI * alphaU*alphaU * const Float cosTheta2 = Frame::cosTheta2(m);
std::pow(Frame::cosTheta(m), (Float) 4.0f));
result = math::fastexp(-exponent) /
(M_PI * alphaU*alphaU*cosTheta2*cosTheta2);
} }
break; break;
case EGGX: { case EGGX: {
/* Empirical GGX distribution function for rough surfaces */ /* Empirical GGX distribution function for rough surfaces */
const Float tanTheta = Frame::tanTheta(m), const Float tanTheta2 = Frame::tanTheta2(m),
cosTheta = Frame::cosTheta(m); cosTheta2 = Frame::cosTheta2(m);
const Float root = alphaU / (cosTheta*cosTheta * const Float root = alphaU / (cosTheta2 *
(alphaU*alphaU + tanTheta*tanTheta)); (alphaU*alphaU + tanTheta2));
result = INV_PI * (root * root); result = INV_PI * (root * root);
} }

View File

@ -1201,17 +1201,21 @@ void export_core() {
.def("toWorld", &Frame::toWorld, BP_RETURN_VALUE) .def("toWorld", &Frame::toWorld, BP_RETURN_VALUE)
.def("__repr__", &Frame::toString) .def("__repr__", &Frame::toString)
.def("cosTheta", &Frame::cosTheta) .def("cosTheta", &Frame::cosTheta)
.def("cosTheta2", &Frame::cosTheta2)
.def("sinTheta", &Frame::sinTheta) .def("sinTheta", &Frame::sinTheta)
.def("sinTheta2", &Frame::sinTheta2) .def("sinTheta2", &Frame::sinTheta2)
.def("tanTheta", &Frame::tanTheta) .def("tanTheta", &Frame::tanTheta)
.def("tanTheta2", &Frame::tanTheta2)
.def("sinPhi", &Frame::sinPhi) .def("sinPhi", &Frame::sinPhi)
.def("cosPhi", &Frame::cosPhi) .def("cosPhi", &Frame::cosPhi)
.def("sinPhi2", &Frame::sinPhi2) .def("sinPhi2", &Frame::sinPhi2)
.def("cosPhi2", &Frame::cosPhi2) .def("cosPhi2", &Frame::cosPhi2)
.staticmethod("cosTheta") .staticmethod("cosTheta")
.staticmethod("cosTheta2")
.staticmethod("sinTheta") .staticmethod("sinTheta")
.staticmethod("sinTheta2") .staticmethod("sinTheta2")
.staticmethod("tanTheta") .staticmethod("tanTheta")
.staticmethod("tanTheta2")
.staticmethod("sinPhi") .staticmethod("sinPhi")
.staticmethod("cosPhi") .staticmethod("cosPhi")
.staticmethod("sinPhi2") .staticmethod("sinPhi2")