WAYNETS.ORG

Game and Program

相机系统

作者:

发表于

Context Polling System Post-Processing Renderer

1. 什么是相机?

在游戏引擎中,相机定义了我们如何看待世界。

相机并不是实际存在的,而是一个数学模型。它决定了场景中哪些物体能被渲染,并如何投射到屏幕二维画面上

在图形学中,相机的核心作用是生成视图矩阵(View Matrix),它将世界空间的物体转换为观察者(相机)空间。

相机系统要做的只是基于我们需要的相机合成变换,改变整个场景的变换。

举个例子:在相机正中心有一个正方体,现在我们希望将镜头向左移动,而实际上移动的是正方体,它在向右移动。

2. 相机中的数学概念

(1)投影矩阵(Projection Matrix)

将摄像机空间中的3D点映射到裁剪空间(Clip Space),再通过透视除法进入屏幕空间。即:将三维场景中的点“投影”到屏幕上的二维平面

投影矩阵决定:视野角度(FOV)、远近范围(近裁剪面/远裁剪面)、是透视还是正交投影。

它描述的是一个相机窗口的形状,不包含位置和朝向信息,即:摄像机镜头。

(2)视图矩阵(View Matrix)

将世界坐标系中的点转换到相机(摄像机)空间中。

视图矩阵决定了相机本身在世界中的位置和朝向(也就是你站在场景哪个位置,面朝哪里)。

它包含位置和方向信息,即:将相机移动到一个点上,朝向一个方向。

总的来说:投影矩阵就像人的眼睛,而视图矩阵就是人的身体

3. 两种投影方式

(1)透视投影(Perspective Projection)

主要用于3D游戏,模拟人眼/相机视角,有“近大远小”的效果。

数学公式:

mat4 projection = perspective(radians(fov), aspectRatio, nearPlane, farPlane);

(2)正交投影(Orthographic Projection)

没有透视缩放,所有物体按原始尺寸呈现。适合 2D 游戏或 UI 渲染。你自己定义一个盒子空间,所有物体按“平行投射”。

数学公式:

mat4 projection = ortho(left, right, bottom, top, near, far);

4. TRS

TRS 是物体变换的三个基本步骤,合称为 模型变换(Model Transform)。我们通过它将物体从“本地坐标系”变换到“世界坐标系”

  • Translate(位移):把物体从原点移动到世界中某个位置。
  • Rotate(旋转):让物体绕某个轴旋转(绕Y轴转头,绕X轴点头,绕Z轴滚动)。
  • Scale(缩放):改变物体的大小。
ModelMatrix = Translation * Rotation * Scale;

5. MVP:Model * View * Projection

这是最终的完整变换矩阵,用于将模型本地空间的顶点变换为裁剪空间,从而渲染到屏幕上。

在实际应用中,它将结合实际顶点位置,获得对象在屏幕上的具体位置:

gl_Position = Projection * View * Model * vec4(VertexPos, 1.0);
gl_Position = MVP * vec4(VertexPos, 1.0);

6. 正交投影摄像机

class OrthographicCamera
{
public:
	OrthographicCamera(float left, float right, float bottom, float top);

	const glm::vec3& GetPosition() const { return m_Position; }
	void SetPosition(const glm::vec3& position) { m_Position = position; RecalculateViewMatrix(); }

	float GetRotation() const { return m_Rotation; }
	void SetRotation(float rotation) { m_Rotation = rotation; RecalculateViewMatrix(); }

	const glm::mat4& GetProjectionMatrix() const { return m_ProjectionMatrix; }
	const glm::mat4& GetViewMatrix() const { return m_ViewMatrix; }
	const glm::mat4& GetViewProjectionMatrix() const { return m_ViewProjectionMatrix; }
private:
	void RecalculateViewMatrix();
private:
	glm::mat4 m_ProjectionMatrix;
	glm::mat4 m_ViewMatrix;
	glm::mat4 m_ViewProjectionMatrix;

	glm::vec3 m_Position = { 0.0f, 0.0f, 0.0f };

	float m_Rotation = 0.0f;
};

定义相机变换位置的数据是一个矩阵,变换矩阵。

变换,旋转

透视矩阵

column major

在Begin Scene的时候,提交一个相机,它会提供一个视图投影矩阵

Leave a comment