视图矩阵的推导


做游戏开发的程序员很少有空去写博客,最近离职后休息了一下,去盛大面试被问到切线空间,之前虽然大致理解了,但是当时又被难到了,

觉得还是要总结一下自己学的东西,讲的清楚才算真正的理解。

 

最近看完了线性代数的本质的一套视频,感觉以前在学校学到的都是渣。

看完后对这种矩阵变换有了个全新的基础认知,据说3D引擎都是从一个软渲染开始,学了部分向量基础后就打算开始学习下这个玩意

软渲染至少得有个向量,矩阵运算的数学库,然后就是lookat函数了,这个函数的主要作用就是构建一个视图矩阵(view矩阵)

view矩阵的目标是把世界坐标系的物体的所有顶点转换到摄像机坐标系(注:这里涉及的矩阵知识点叫基变换

基变换的推导基本如下,涉及的知识点挺多:(基向量,矩阵线性变换,逆矩阵,单位矩阵,向量张成空间,正交矩阵,矩阵转置)

摄像机在2个坐标系有2个位置

第1个是世界坐标系基向量通过旋转平移得到摄像机的3个基向量在世界坐标系的位置

第2个是摄像机坐标系中3个基向量相对自己原点的标准基向量

摄像机的3个基向量在世界坐标系中的张成空间是整个空间(注:就是表示空间中的任何一个向量都可以用摄像机在世界坐标系中的3个向量通过乘以某个系数来表示,就好像y=x可以表示2维坐标系里斜率为45度角的所有点)

那么我们这里也可以把世界坐标系中的某个向量表示成类似结果:世界坐标系中的某个向量 = 系数1 * 摄像机在世界坐标系的3个基向量

这个系数1就是这个向量在摄像机坐标系中的所表示的向量

我们来进一步拆分上面的公式,摄像机的3个基向量也有上面类似的结论,因为世界坐标系的3个基向量也是张成整个空间,也就是说摄像机的每个基向量也可以通过世界坐标的3个基向量乘以某个系数2表示

那么公式就可以写成:世界坐标系中的某个向量 = 系数1 * 系数2 * 世界坐标系的基向量

如果是2D的数序,我们知道要去求系数1,就是除以系数2和世界坐标系的基向量

在线性代数里这个系数1和系数2都表示某种矩阵变换,除法的表示方法是两边各乘以一个矩阵的逆

 那么最后的公式就是: 系数1 = 世界坐标系中的某个向量 * 系数2的逆 * 世界坐标系的基向量的逆

 转化下最后的意思是这样:任意在视图坐标系表示的坐标 = 这个坐标在世界坐标系的坐标 * 摄像机线性变换的逆 * 世界坐标系单位矩阵的逆

世界坐标系单位矩阵的逆就是自身,单位矩阵做为变换参与运算时,转换结果不变(这个是很重要的性质)

那么公式就可以简化为:任意在视图坐标系表示的坐标 = 这个坐标在世界坐标系的坐标 * 摄像机线性变换的逆 

就像开头所说view矩阵的目标是把世界坐标系的物体的所有顶点转换到摄像机坐标系,那么这个摄像机线性变换的逆就是我们需要的view矩阵

 

 这样我们就可以开始拷贝网上别人的一些图跟代码来表示下了。

看看lookat的 3个位置向量

1个是眼睛的位置 eyePos

1个是看的目标点位置 tarPos

剩下1个是摄像机头顶方向upVec(0,1,0)

先求出摄像机的3个基向量(U,V,W),基向量是互相垂直的3个单位向量

视线方向是眼睛指向目标,所以是tarPos-eyePos得到viewDir.normalize(),这个就是W了,基向量必须单位化

根据头顶方向upVec跟W可以通过叉积得到跟这2个向量组成的屏幕垂直的向量,U = W x upVec

upVec虽然向上,但不一定跟W,U垂直,所以重新求V,同上V = W x U

这样就得到U,V,W 3个基向量了,也就是下面的C,

C可以拆分成平移和旋转2个变换, image,其中T是平移变化,R是旋转变化,他的逆变换就是 image

 

T的逆矩阵为:

image

opengl的矩阵每行可以拆分成 x,y,z,w ,w是平移的成分,x,y,z就是旋转的成分了。

上面的U,V,W是只有旋转没有平移的R了。

所以就有了这个

完整的公式为:image      image

注意:这里又有个重要性质,正交矩阵的逆矩阵就是就是它的转置矩阵

 

R是正交矩阵,所以R的逆就是R的转置矩阵 ,注意看,行列是互换的。

以上就是视图矩阵推导完整过程


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM