书接上回OpenGL-0x09-矩阵变化,相机的本质是要提供从相机视角的观察矩阵。但是从投影矩阵的公式可以看到几个变量
- 视野角度
- 宽高比=视口宽度/视口高度
- 近距离
- 远距离
在每一帧中,可能会进行缩放视口,所以投影矩阵也会在每一帧进行变换。那么如果让相机持有投影矩阵P,然后自己又可以提供观察矩阵M,其实客户端就可以得到P*M。
1 相机对客户端的交付
1 2 3 4 5 6 7 8 9
|
glm::mat4 GetViewProjection() const { return m_projection * m_viewMatrix; }
|
2 投影矩阵的更新计算
1 2 3 4 5 6 7 8 9 10
| void EditorCamera::updateProjection() { m_aspectRatio = m_viewportWidth / m_viewportHeight; m_projection = glm::perspective(glm::radians(m_fov), m_aspectRatio, m_nearClip, m_farClip ); }
|
3 相机的观察矩阵
1 2 3 4 5 6 7 8 9 10
| void EditorCamera::updateView() { m_position = calculatePosition(); glm::quat orientation = GetOrientation(); m_viewMatrix = glm::translate(glm::mat4(1.0f), m_position) * glm::toMat4(orientation); m_viewMatrix = glm::inverse(m_viewMatrix); }
|
关于相机的运动,分为自由移动和视角移动
- 自由移动改变的是相机的位置
- 视角移动改变的是欧拉角
3.1 关于相机位置
1 2 3 4
| glm::vec3 EditorCamera::calculatePosition() const { return m_focalPoint - GetForwardDirection() * m_distance; }
|
相机位置是通过焦点位置计算出来的,所以相机的自由移动改变的是
进而,每次移动完就计算出来最新的相机位置
3.2 关于四元数
1 2 3 4 5 6 7
| glm::quat EditorCamera::GetOrientation() const { return glm::quat(glm::vec3(-m_pitch, -m_yaw, 0.0f )); }
|
相机的欧拉角信息用四元数存起来,用的时候直接用四元数计算。