首页 > 解决方案 > 如何保证齐次坐标中的向量经过变换后仍然是向量

问题描述

MVP transformation在模型的顶点上执行了一个。理论上,我必须将 MVP 变换的逆转置矩阵应用于normal

这是推导过程:</p>

(A, B, C)是该点(x, y, z)所在 平面的法线在此处输入图像描述

对于一个向量,例如(x0, y0, z0),它(x0, y0, z0, 0)在齐次坐标中。变换后应该还是一个向量,如(x1, y1, z1, 0),这就要求4*4变换矩阵的最后一行除了最后一列的元素外全部为0,否则(x1, y1, z1, n)变换后就变成了。

事实上,我的 MVP 变换矩阵在经过反转置变换后无法满足这一点。

代码:

Mat<4, 4> View(const Vec3& pos){
    Mat<4, 4> pan{1, 0, 0, -pos.x,
                0, 1, 0, -pos.y,
                0, 0, 1, -pos.z,
                0, 0, 0, 1};
    Vec3 v = Cross(camera.lookAt, camera.upDirection).Normalize();
    Mat<4, 4> rotate{v.x, v.y, v.z, 0,
                     camera.upDirection.x, camera.upDirection.y, camera.upDirection.z, 0,
                     -camera.lookAt.x, -camera.lookAt.y, -camera.lookAt.z, 0,
                     0, 0, 0, 1};
    return rotate * pan;
}

Mat<4, 4> Projection(double near, double far, double fov, double aspectRatio){
    double angle = fov * PI / 180;

    double t = -near * tan(angle / 2);
    double b = -t;
    double r = t * aspectRatio;
    double l = -r;

    Mat<4, 4> zoom{2 / (r - l), 0, 0, 0,
                    0, 2 / (t - b), 0, 0,
                    0, 0, 2 / (near - far), 0,
                    0, 0, 0, 1};
    Mat<4, 4> pan{1, 0, 0, -(l + r) / 2,
                    0, 1, 0, -(t + b) / 2,
                    0, 0, 1, -(near + far) / 2,
                    0, 0, 0, 1};
    Mat<4, 4> extrusion{near, 0, 0, 0,
                        0, near, 0, 0,
                        0, 0, near + far, -near * far,
                        0, 0, 1, 0};

    Mat<4, 4> ret = zoom * pan * extrusion;
    return ret;
}
Mat<4, 4> modelMatrix = Mat<4, 4>::identity();
Mat<4, 4> viewMatrix = View(camera.position);
Mat<4, 4> projectionMatrix = Projection(-0.1, -50, camera.fov, camera.aspectRatio);
Mat<4, 4> mvp = projectionMatrix * viewMatrix * modelMatrix;
Mat<4, 4> mvpInverseTranspose = mvp.Inverse().Transpose();

MVP:

-2.29032  0        0.763441   -2.68032e-16 
0         -2.41421 0          0 
-0.317495 0        -0.952486  2.97455 
0.316228  0        0.948683   -3.16228 

mvpInverseTranspose:

-0.392957   0          0.130986   0 
0           -0.414214  0          0 
-4.99       0          -14.97     -4.99 
-4.69377    0          -14.0813   -5.01

标签: c++matrixgraphics

解决方案


我似乎明白了这个问题。光照应该是在世界空间中计算的,所以我只需要将 的逆转置矩阵the model transformation应用于normal


推荐阅读