要通过屏幕像素坐标反推世界坐标,就要知道世界坐标是如何变换为屏幕坐标的。理论上,将世界坐标(x, y, z)变换为(u, v, d)的过程如下:
第一步,将坐标点(x, y, z, 1)乘以从世界坐标系到相机坐标系的转换矩阵(World-to-Camera 4x4 Matrix),将坐标点(x, y, z, 1)变换为相机空间(Camera Space)坐标,转换后的坐标为(x1, y1, z1, w1),其中w1 = 1。
第二步,将相机空间坐标乘以从相机坐标系到裁剪空间(Clipping Space)坐标系的投影矩阵(Projection 4x4 Matrix),将坐标点转换到裁剪空间,转换后的坐标为(x2, y2, z2, w2),其中w2 = -z1。在Unity中,如果坐标点位于视锥体内(z1 > 0),那么x2,y2的范围都是[-z1, z1],z2的范围是[-z1, 0]。也就是说,我们可以想象这一步是将视锥体“压扁”成一个半立方体。
第三步,将裁剪空间中的坐标(x2, y2, z2, w2)除以w2,得到一个归一化的坐标(x3, y3, z3, 1),也就是说,x3, y3的范围是[-1, 1],z3的范围是[0, 1]。 根据摄像机投影的屏幕区域(通常是整个屏幕)和x3, y3,就可以得知这个坐标点在屏幕上的位置。z3则是深度。