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;
}
/** \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
* system, return the cosine of the angle between the normal and v */
inline static Float cosTheta(const Vector &v) {
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
* system, return the sine of the angle between the normal and 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
* 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;
* system, return the squared tangent of the angle between the normal and v */
inline static Float tanTheta2(const Vector &v) {
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

View File

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

View File

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