OpenGL是右手坐标系,z轴朝外,z值范围是【-1,1】,摄像机的前方的物体在摄像机坐标系下的z值为负数,Direct3D是左手坐标系,z轴朝屏幕里,z值范围是【0,1】,摄像机的前方的物体在摄像机坐标系下的z值为正数,所以OpenGL和Direct3D下的投影矩阵就有所不同。
假设投影矩阵为(列主序):
x1 0 0 0
0 x2 0 0
0 0 a b
0 0 c 0
摄像机的近远裁剪面分别为n,f,有一点P(x,y,z,1),投影后为P(x1*x, x2*y, a*z+b, c*z)。
OpenGL的情况:
1、c*z:z为负值,c*z为正值,所以c=-1。
2、a*z+b:当z在【-n,-f】范围时,(a*z+b)/c*z必须在【-1,1】范围内,所以a=-(f+n)/(f-n),b=-2*f*n/(f-n)。
3、投影矩阵为:
x1 0 0 0
0 x2 0 0
0 0 -(f+n)/(f-n) -2*f*n/(f-n)
0 0 -1 0
Direct3D的情况:
1、c*z:z为正值,c*z为正值了,所以c=1。
2、a*z+b:当z在【n,f】范围时,(a*z+b)/c*z必须在【0,1】范围内,所以a=f/(f-n),b=-f*n/(f-n)。
3、投影矩阵为:
x1 0 0 0
0 x2 0 0
0 0 f/(f-n) -f*n/(f-n)
0 0 1 0