在记录此文前看过许多3D介绍的书籍,却总未能理解相机坐标至空间坐标转换的情况,网上搜索亦五花八门,多是文章转载,时而见文式有误亦未有异议,尚未知其人是否曾读此文章。因而自己推导与想像,总算能观其义。故记此文以记。(-_-!!最近古文看多了……)
在许多书籍中提到的相机坐标到投影空间坐标的变换,通常只用一个图片表示屏幕坐标与投影空间坐标及屏幕坐标的变换,导致理解得蒙查查;更有直接给出相机坐标到屏幕坐标一步到位的矩阵公式,却解释得不知所云。
以下是我理解转换的过程。
设屏幕的宽高比为ratio = WIDTH*HEIGHT,theta为可视角度,取值范围为[0, 180)。
相机坐标到投影空间的转换是在相机空间内将相机width*height的可视锥范围内的点投影到距离视点(即原点)距离为d的N*N正方形①。由于通常而言,屏幕的宽高比不同,因此相同视距中,投影到矩形时比例不一定为1:1。故此时根据不同情形将投影范围进行拉伸/缩放(下方右图分别表示在以宽/高作标准投影计算时其投影范围的情况[此处图片假定width > height])。
设投影矩形的大小为N*N,其中心位于观察方向(即Z轴),以视宽作为投影范围标准,则d = cot(theta/2) * N / 2,相机锥内的点p(x, y, z)其相关投影坐标公式为
xd = N * d * xp / (2 * zp)yd = ratio * N * d * yp / (2 * zp)
投影矩形的大小一般设定为2*2或1*1。以2*2为例,其投影矩形的左下角坐标为(-1, -1),右上角坐标为(1, 1),则相关的投影坐标公式为xd= d * xp/ zp, yd= ratio * d * yp/ zp。
至此,相机坐标点即转换为投影坐标。
最后,投影坐标到屏幕的坐标转换公式为(假定使用左手坐标系)
xs = (WIDTH * xd + WIDTH) / N
ys = (-HEIGHT * yd + HEIGHT) / N
(上述中的 width 和 height 根据不同游戏的设置以设定其大小与单位。)
① 投影的范围必须是正方形么?
不必,但如果不将投影范围设定为方形,则在将非标准的投影坐标转换为屏幕坐标时需要进行拉伸/缩放,实际上即是将投影范围的拉伸/缩放操作延迟至屏幕坐标转换时执行。