具体在书p275页 这里为啥需要除D.w呢。 首先我们得到的NDC的坐标是已经归一化的,但是CurrenViewProjectionInverseMatrix的作用,是把世界空间转化为尚未归一化的裁剪空间。 这里书上有说明。 然后查找Unity的函数得知变换得到的顶点坐标是没有归一化的 Camera.projectionMatrix.
static Matrix4x4 PerspectiveOffCenter(float left, float right, float bottom, float top, float near, float far)
{
float x = 2.0F * near / (right - left);
float y = 2.0F * near / (top - bottom);
float a = (right + left) / (right - left);
float b = (top + bottom) / (top - bottom);
float c = -(far + near) / (far - near);
float d = -(2.0F * far * near) / (far - near);
float e = -1.0F;
Matrix4x4 m = new Matrix4x4();
m[0, 0] = x;
m[0, 1] = 0;
m[0, 2] = a;
m[0, 3] = 0;
m[1, 0] = 0;
m[1, 1] = y;
m[1, 2] = b;
m[1, 3] = 0;
m[2, 0] = 0;
m[2, 1] = 0;
m[2, 2] = c;
m[2, 3] = d;
m[3, 0] = 0;
m[3, 1] = 0;
m[3, 2] = e;
m[3, 3] = 0;
return m;
}
}
根据书上的描述我们可以得到等式
-
worldPos * CurrenViewProjectionMatrix / w = NDC 把worldPos看成(x, y , z ,1) -
即 (x / w, y / w, z / w, 1 / w) = NDC * CurrenViewProjectionInverseMatrix 右边也就是前一行代码计算得到的,然后 -
worldPos / worldPos.w 即为( x / w, y / w, z / w, 1 / w) / (1 / w) -
即为(x , y , z ,1)
还是有点妙的,这里是利用了已知worldPos的w原本值为1的特性进行计算
|