大家好,又见面了,我是你们的朋友全栈君。
概要
投影变换是计算机图形学的基础,理解并推导投影矩阵也是很有必要的。正交投影比较简单,没有透视失真效果(近大远小)。而透视投影比较符合人类的眼睛感知,平行线在远处会相交于一点。 投影是通过一个4×4的矩阵来完成的,将视锥映射成标准观察体(齐次裁剪空间)。
正交投影
OpenGL
OpenGL采用的是右手坐标系,z轴朝屏幕向外,因此观察方向是朝着z轴负方向的,那么将x,y,z坐标从区间[l, r], [b,t], [-n, -f]映射到[-1, 1]的函数为:
得到投影矩阵:
当然也可以用一个平移和缩放矩阵的级联矩阵,来达到一样的效果。
DirectX
DirectX则是采用左手坐标系,z轴和观察方向是一致的,因此只需要将z轴坐标从[n, f]映射到[0, 1],x和y轴则和OpenGL是一样的。
透视投影
OpenGL
设P(Px, Py, Pz, 1)是在视锥体内的一点,那么它在近平面z=-n上的投影点,利用相似三角形原则,可以得到:
类似于正交投影,将x,y轴坐标映射到[-1, 1]区间内,得到:
然而和正交投影不同,z轴的坐标并不是线性的。在光栅化过程中,必须对z坐标的倒数进行插值,因此需要建立1/z的映射函数,这样就可以对投影深度进行插值,映射函数的形式如下:
将[-n, -f]映射到[-1, 1],可以得到:
解这个简单的二元一次方程组,可以得到A,B的值
这样就得到了z轴上的映射函数:
3D点(x, y, z)等价于齐次坐标(-xPz, -yPz, -zPz, -Pz),因此x,y,z分量都乘以-Pz得到:
得到投影矩阵:
变换后的齐次坐标,w分量为-Pz,
DirectX
DirectX的区别在于近平面为z=n,并且要将[n, f]映射到[0, 1],经过类似的计算,可以得到
得到投影矩阵:
参考资料
《3D游戏与计算机图形学中的数学方法》 《实时计算机图形学2nd》
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/185976.html原文链接:https://javaforall.cn