raytracing.github.io
raytracing.github.io copied to clipboard
Book 3 8.3: onb class, axis calculation for u and v should be swapped
class onb {
public:
onb(const vec3& n) {
axis[2] = unit_vector(n);
vec3 a = (std::fabs(axis[2].x()) > 0.9) ? vec3(0,1,0) : vec3(1,0,0);
axis[1] = unit_vector(cross(axis[2], a));
axis[0] = cross(axis[2], axis[1]);
}
const vec3& u() const { return axis[0]; }
const vec3& v() const { return axis[1]; }
const vec3& w() const { return axis[2]; }
vec3 transform(const vec3& v) const {
// Transform from basis coordinates to local space.
return (v[0] * axis[0]) + (v[1] * axis[1]) + (v[2] * axis[2]);
}
private:
vec3 axis[3];
};
According to the code in vec3.h and the whole context, the following statements are true:
- The coordinate system is right-handed.
- order of axis[3] is
u, v, wwhere w is the normal vector in basis coordinate.
Then to make sense, the constructor should be like this,
axis[0] = unit_vector(cross(axis[2], a));
axis[1] = cross(axis[2], axis[0]); // w cross u is v
to make the final result satisfy the following statements,
\begin{align}
\vec{\bf{w}} = \vec{\bf{u}} \times \vec{\bf{v}} \\
\vec{\bf{u}} = \vec{\bf{v}} \times \vec{\bf{w}} \\
\vec{\bf{v}} = \vec{\bf{w}} \times \vec{\bf{u}}
\end{align}
Yeah, I think so. (It won’t actually affect rendering in this code, but I’m still inclined to change it for clearer understanding.)