写完模拟器的M3G部分,早就想写点总结,不写怕要忘了。那就从最简单的Camera类开始。
Camera类封装了3种投影变换:Generic、Parallel、Perspective。1) Genericpublic void setGeneric(Transform transform)直接指定一个变换矩阵(Transform类其实就是一个矩阵的封装),可以根据需求任意设置投影矩阵。
2) Parallelpublic void setParallel(float fovy, float aspectRatio, float near, float far) 平行投影(正射投影,Orthographic Projection),忽略z轴作用,投影后的物体大小尺寸不变。M3G Specification中已经给出了对应的矩阵(NDC坐标系): | 2/w 0 0 0 | | 0 2/h 0 0 | | 0 0 -2/d -(near+far)/d | | 0 0 0 1 |其中,fovy - height of the view volume in camera coordinates。h = height (= fovy)w = aspectRatio * hd = far - near
公式推导:
设(x, y, z, w)为视点坐标,(x’, y’, z’, w’)为投影坐标,(Px, Py, Pz, Pw)为NDC。近平面距离为n,远平面距离为f,视口宽为w,高为h。 x’ = x y’ = y映射到NDC ([-1, 1]), Px = 2 * x’/ w = 2 * x / w Py = 2 * y’ / h = 2 * y / h由于z坐标投影后不参与绘图,用于可见性判断,只要保证Pz与z呈线性关系,即Pz=a*z+b将(-n,-1), (-f, 1) 代入得 a = -2 / (f - n)b = -(n + f) / (f - n)Pz = -2/ (f - n)*z - (n + f) / (f - n)即等价于 | x | | 2/ w 0 0 0 | | y | | 0 2 / h 0 0 | | z | * | 0 0 -2/ (f – n) -( n + f) / (f - n) | | 1 | | 0 0 0 1 |
3) Perspectivepublic void setPerspective(float fovy, float aspectRatio, float near, float far) 透视投影,即离视点近的物体大,离视点远的物体小,符合人们心理习惯。M3G Specification中已经给出了对应的矩阵(NDC坐标系): | 1/w 0 0 0 | | 0 1/h 0 0 | | 0 0 -(near+far)/d -2*near*far/d | | 0 0 -1 0 |其中,fovy - field of view in the vertical direction, in degrees。h = tan ( fovy/2 ) w = aspectRatio * hd = far - near
公式推导:
设(x, y, z, w)为视点坐标,(x’, y’, z’, w’)为投影坐标,(Px, Py, Pz, Pw)为NDC。近平面距离为n,远平面距离为f,近平面宽为W,高为H。由相识三角形可以得到x’ = -n * x / zy’ = -n * y / z映射到NDC ([-1, 1]),可得 Px = x’/ (W/2) = -2*n*x / z * W Py = y’/ (H/2) = -2*n*y / z * H由于x’, y’与1/ z有线性关系,只要保证Pz与1/z呈线性关系,即Pz=a/z+b将(-n,-1), (-f, 1) 代入得 a = 2*n*f / f - nb = f + n / f – nPz = 2*n*f / (f - n)*z + (f+n) / (f - n)由于最后会除以w分量,所以可以把共同项写入w分量: -zPx = 2*n*x / W -zPy = 2*n*y / H -zPz = -2*n*f / (f – n) - (f+n) / (f - n) * z w = -z即等价于 | x | | 2*n / W 0 0 0 | | y | | 0 2*n / H 0 0 | | z | * | 0 0 - (f+n) / (f - n) -2*n*f / (f – n) | | 1 | | 0 0 -1 0 |
引入视角fovy,即: h = tan ( fovy/2 ) = (H/2) / n = H / 2*n w = aspectRatio * h = W / 2*nd = f - n
=============
不知道有没有下文。。。。