minor optimization (save a few square roots here and there)
parent
06d6b96c6e
commit
f9d42ff3b2
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue