文章目录
顶点数据分析如何变换到世界空间:Model_Matrix缩放rotate_matrix旋转平移如何变换到摄像机空间:View_Matrix如何使视图更加符合人眼视角(产生近大远小效果):Projection_Matrix裁剪空间具体做了啥如何变换到屏幕像素点空间: Viewport_Matrix深度测试首先放一张图震文^^
下文的讨论都和这个变换过程密切相关。并且本文不对基础的线性代数进行介绍,比如向量,矩阵,逆,转置的概念就不介绍了(本小白比较懒==)。
顶点数据分析
想从变换一个立方体的坐标开始着手。每一个物体都有自己的local坐标系,比如一个简单的正方体,它就自己的local坐标系。
如何变换到世界空间:Model_Matrix
缩放rotate_matrix
把缩放放在前面介绍,就是因为在具体的操作时,要先对向量左乘上rotate_matrix,(如果先平移or旋转再进行缩放的,可能会把平移or旋转的距离也缩放了,可以实验验证一下)。
旋转矩阵比较简单,如下图左边的矩阵。将这个矩阵乘在向量左边就得到最终的变换后的坐标(向量)了。
旋转
对于绕坐标轴的旋转矩阵,栗子:绕x轴顺时针旋转theta角度,如下图的第一个公式。绕y轴顺时针旋转theta角度,绕z轴顺时针旋转theta角度类似。
当然只是绕固定轴是无法满足需求的,伟大的数学家们找到了下面的绕任意轴的旋转矩阵公式。其中(Rx ,Ry ,Rz )表示任意旋转轴
平移
如何变换到摄像机空间:View_Matrix
经过上一步的变换,此时的正方体坐标已经不再是local空间里的了,而是对应到世界空间中的位置(比如我们可以规定它先缩放至原来1/2,向x轴方向移动100,绕x轴旋转45°,得到的8个点的坐标一定和原来是不同的)。
但是我们希望从上帝视角观察一个物体,犹如在画面中扛着摄像机记录一个画面(想象第一人称设计游戏的画面),就必须要计算物体在摄像机空间的坐标。
贴上一个大佬的文章,讲的比较详细。
计算View_Matrix主要就是要理解,R基和T基,T-1 就是逆变换一个物体需要的平移矩阵逆,RT 就是逆变换一个物体需要的旋转矩阵转置(其实本来是逆,但是正交矩阵的转置和逆是相等的,而转置又比较好计算,所以你懂啦),乘一下就是View_Matrix:C-1了。下面的表达式中,U表示右向量,V表示上向量,N表示目标指向相机的向量,T表示摄像机在世界空间的坐标
真理尽在闫令琪大佬的视频中
如何使视图更加符合人眼视角(产生近大远小效果):Projection_Matrix
要知道两种投影方式:正交投影和透视投影
正交投影更接近真实世界的点线面特征,仿佛就把三维空间的物体直接拍到二维平面上的投影。正交投影矩阵见下图(来自闫令琪大神的课程讲义)
然后根据闫神的讲义,推导的正交矩阵如下:
透视投影要把原先的立方体不规则的压缩一下,然后再拍在二维屏幕上。预知矩阵推导请戳闫佬教程。传送门~
把空间压成一个四棱锥箱子
再通过透射投影拍到屏幕上去。
注意:在OpenGL中NDC使用的是左手坐标系(投影矩阵交换了左右手),在闫神的讲解中使用的完全是右手坐标系。所以推导的公式可能有些不同。下面这个为右手坐标系下的透视投影矩阵
但是注意,在OpenGL中此时最好使用左手坐标系,把上面公式中的1改为-1,这样才能避免在后面的除以w(实际就是除z)操作中坐标的正负值颠倒。
本文的项目使用的是左手坐标系,代码中所用公式如下:
图示如下,其中a就是fov
裁剪空间具体做了啥
假如你进行透视投影变换,那么此时的坐标(x,y,z,w)的w值就不是原先设定的1了,如果直接将向量值左乘以Viewport_Matrix传到屏幕空间,那么是绝对画不出任何图形的,所以要在此时将w值变为1,即向量的所有分量都除以w就可。此时x,y,z的范围都在(-1.1)。本文和一些说法在此处有些不同,因为本文没有同OpenGL一样在投影时变换左右手坐标系。
如何变换到屏幕像素点空间: Viewport_Matrix
就是将每个点(x,y,z,w)中的x,y对应到屏幕空间具体的像素值。
具体的转换这篇讲的很细(是的我又偷懒了==)传送门
深度测试
x值,y值已经通过Viewport_Matrix变换到屏幕空间了,z值也变换到0-1的范围了。在x值和y值的约束下进行绘制比较好理解,就是一行行扫描光栅化就行了。但是每个点的z值决定了该点会不会被绘制出来。如何计算z值?(即给定三角形的三个顶点像素坐标[x,y,z,w],和屏幕某点像素点坐标[x,y],如何计算像素点的z值)
给三角形的三个顶点,插值出三角形内任意一点的z值方法:
重心坐标法(“重心坐标” 不是 “重心”)就是求出该点的重心坐标
重心坐标法的思想戳这里
上图公式可以看出,给定要求顶点的[x,y],三个顶点的[x,y,z]就可以通过计算出alpha,beta,gamma得出所求顶点的z值。
得到的z值是线性平均
最后 终于画出了汪==下一篇介绍透视投影带来的几种需要透视矫正的情况。