# Inverted yaw angle in the view matrix

I'm trying to construct a FPS view matrix for my OpenGL renderer using yaw and pitch angles instead of the typical LookAt view matrix.

The view matrix is the inverse of the camera world transform $\mathbf{M}_{\textrm{view}} = (\mathbf{T}\mathbf{R}_p\mathbf{R}_y)^{-1}$, hence:

\small\begin{align} (\mathbf{T}\mathbf{R}_p\mathbf{R}_y)^{-1} &= \mathbf{R}_y^{T}\mathbf{R}_p^{T}\mathbf{T}^{-1} \\ &= \begin{bmatrix} \cos{y} & 0 & \sin{y} & 0 \\ 0 & 1 & 0 & 0 \\ -\sin{y} & 0 & \cos{y} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}^T \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos{p} & -\sin{p} & 0 \\ 0 & \sin{p} & \cos{p} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}^T \begin{bmatrix} 1 & 0 & 0 & e_0 \\ 0 & 1 & 0 & e_1 \\ 0 & 0 & 1 & e_2 \\ 0 & 0 & 0 & 1 \end{bmatrix}^{-1} \\ &= \begin{bmatrix} \cos{y} & 0 & -\sin{y} & 0\\ 0 & 1 & 0 & 0 \\ \sin{y} & 0 & \cos{y} & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & 0\\ 0 & \cos{p} & \sin{p} & 0\\ 0 & -\sin{p} & \cos{p} & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & -e_0\\ 0 & 1 & 0 & -e_1\\ 0 & 0 & 1 & -e_2\\ 0 & 0 & 0 & 1\\ \end{bmatrix} \\ &= \begin{bmatrix} \cos{y} & \sin{p}\sin{y} & -\cos{p}\sin{y} & -e_0\cos{y} - e_1\sin{p}\sin{y} + e_2\cos{p}\sin{y}\\ 0 & \cos{p} & \sin{p} & -e_0 \cdot 0 - e_1 \cos{p} - e_2 \sin{p}\\ \sin{y} & -\cos{y}\sin{p} & \cos{p}\cos{y} & -e_0\sin{y} + e_1\cos{y}\sin{p} - e_2\cos{p}\cos{y}\\ 0 & 0 & 0 & 1 \end{bmatrix} \end{align}

Every step is double checked using WolframAlpha.

The implementation:

inline Matrix4
FPSViewRH(const Vector3& eyePosition, float yaw, float pitch) noexcept
{

const auto sinYaw = std::sin(yaw);
const auto cosYaw = std::cos(yaw);

const auto sinPitch = std::sin(pitch);
const auto cosPitch = std::cos(pitch);

const Vector3 i{cosYaw, sinPitch * sinYaw, -cosPitch * sinYaw};
const Vector3 j{0, cosPitch, sinPitch};
const Vector3 k{sinYaw, -cosYaw * sinPitch, cosPitch * cosYaw};

return {
{i[0], i[1], i[2], -i.Dot(eyePosition)},
{j[0], j[1], j[2], -j.Dot(eyePosition)},
{k[0], k[1], k[2], -k.Dot(eyePosition)},
{0,    0,    0,    1},
};
}


It works fine except that the yaw is inverted, i.e. increasing the angle causes the object to go right while it should go left.

I can negate the yaw angle or change every $\sin{y}$ to $-\sin{y}$, but I don't really understand why this is happening?

• In case it provides any help, according to 3dgep.com/understanding-the-view-matrix/#Look_At_Camera some signs are changed, which would not make sense according to me, as it does not make sense with the rotation matrix multiplication results. You can check that in the FPS camera section Commented Sep 26, 2020 at 17:51
• Oh In the case if the example provided it says that "The basic theory of this camera model is that we want to build a camera matrix that first rotates pitch angle about the X axis, then rotates yaw angle about the Y axis, then translates to some position in the world" that means that the order of the rotation is inverted. So if I do RpT * RyT, the signs are correct. Sorry if that was confusing Commented Sep 26, 2020 at 18:00

It's happening because they just happened to define the rotation matrix with counterclockwise rotation direction, which is the common convention for polar$\rightarrow$cartesian coordinate system transformation. If you google for the transformation, you'll see that the angle is universally shown to rotate to the counterclockwise direction like below