MVP 变换是在计算机图形学中常用的一个概念,它代表了 Model-View-Projection 三个变换的组合。这三个变换分别对应了物体空间(Model)、摄像机空间(View)和投影空间(Projection)的变换。
Model 变换:这个变换将物体从其自身的坐标系(也称为物体空间或局部空间)转换到世界坐标系中。这通常涉及到平移(移动物体的位置)、旋转(改变物体的方向)和缩放(改变物体的大小)。
View 变换:这个变换将物体从世界坐标系转换到摄像机或者说观察者的坐标系中。这通常涉及到的是摄像机的位置和朝向。
Projection 变换:这个变换将物体从摄像机坐标系转换到投影坐标系中,也就是将三维空间中的物体投影到二维的屏幕上。这通常涉及到的是透视投影(Perspective Projection)或正交投影(Orthographic Projection)。
在实际应用中,这三个变换通常会合并到一个矩阵中,称为 MVP 矩阵,用于在顶点着色器中一次性完成所有的坐标变换。这个 MVP 矩阵就是 Model 矩阵、View 矩阵和 Projection 矩阵的乘积:
MVP = Projection * View * Model
这里的乘法是从右到左进行的,所以首先应用 Model 变换,然后应用 View 变换,最后应用 Projection 变换。
简单理解就是:先在模型上修改,然后把相机移过去,最后投影到相机屏幕上。
视图变换
在 MVP(Model-View-Projection)变换中,View 矩阵代表了摄像机或者说观察者的坐标系。它负责将世界坐标系中的物体转换到摄像机坐标系中。
直观地理解,
你可以将 View 矩阵看作是定义了“摄像机”的属性。它决定了我们从哪个角度和位置看世界。换句话说,View 矩阵定义了世界如何相对于摄像机移动和旋转。
例如,如果你想让摄像机向上移动,实际上你是在将整个世界向下移动。如果你想让摄像机向右旋转,实际上你是在将整个世界向左旋转。这就是为什么 View 矩阵通常包含的变换是平移和旋转的逆变换。
因此,View 矩阵可以看作是一种“反世界”变换,它将所有的物体从世界空间转换到摄像机空间,使得摄像机看起来像是在原点,朝向特定的方向(通常是Z轴负方向)。
数学上
在计算机图形学中,V矩阵(View Matrix)通常用于描述摄像机(或观察者)的位置和方向。V矩阵是一个4x4的矩阵,可以通过以下方式计算:
首先,我们需要定义三个向量:摄像机位置(eye)、目标位置(target)和向上向量(up)。
然后,我们可以计算出三个基向量:前向(forward)、右向(right)和上向(upward)。
前向向量是摄像机位置指向目标位置的向量,右向向量是向上向量与前向向量的叉积,上向向量是前向向量与右向向量的叉积。
最后,我们可以将这三个基向量和摄像机位置组合成V矩阵。
以下是计算V矩阵的伪代码:
vec3 forward = normalize(eye - target)
vec3 right = normalize(cross(up, forward))
vec3 upward = cross(forward, right)
mat4 viewMatrix = mat4(
vec4(right, 0),
vec4(upward, 0),
vec4(forward, 0),
vec4(-dot(right, eye), -dot(upward, eye), -dot(forward, eye), 1)
)
这里,normalize
函数用于将向量归一化,cross
函数用于计算两个向量的叉积,dot
函数用于计算两个向量的点积,vec3
和vec4
用于创建三维和四维向量,mat4
用于创建4x4矩阵。
这一行代码是在构建视图矩阵的最后一行,它代表了摄像机(或观察者)在世界坐标系中的位置。
vec4(-dot(right, eye), -dot(upward, eye), -dot(forward, eye), 1)
这个表达式的前三个元素是摄像机位置的负向量在右向、上向和前向基向量上的投影。这是因为我们需要将世界坐标系转换到摄像机坐标系,这个过程可以看作是将世界坐标系沿着摄像机的位置向量平移的反方向,然后再进行旋转。
具体来说,-dot(right, eye)
计算的是摄像机位置向量在右向基向量上的投影的负值,-dot(upward, eye)
计算的是摄像机位置向量在上向基向量上的投影的负值,-dot(forward, eye)
计算的是摄像机位置向量在前向基向量上的投影的负值。
最后一个元素1是齐次坐标的一部分,用于支持平移变换。在这里,它的值是1,表示这是一个位置向量,而不是一个方向向量。
注意:这里用到的是行主序。