中矩阵怎么编写_基础教程2—向量和矩阵在游戏世界应用

向量和矩阵在游戏中的应用 上一章中我们讲解了对向量和矩阵的理解,进而引出线性变换的概念,线性变换所使用的变量——矩阵是可以把对物体的旋转变换和缩放变换统一起来得变量。线性变换在处理大规模点变换的时候是非常有利的,而且易于硬件实现,进而提高运算效率。这章里我们就谈谈线性变换如何在游戏中使用。 游戏世界和现实世界是相似的,都是有很多变化中的物体组成的,只不过现实世界中物体的变换遵循着复杂的物理规律且连续,而游戏因为是运行在计算设备上,这些设备有运算能力和显示能力的限制,所以游戏中会大大简化物体的变化方式,且每隔一段时间才会把物体绘制在显示器上,故它的运行是不连续的,虽然有很多的不同,但是他们用到的数学基础却是一样的。其实不管是现实世界还是游戏世界,都是很多变化物体的合集,而物体的各种变化就离不开上一章讲到的线性变换。 一、仿射变换推导和理解 上一章中我们留有两个问题没有解决,第一个是线性变换不能对在原点的物体进行平移操作,第二个是线性变换对不在原点的物体的计算比较复杂。由于以上两个问题的存在,那么游戏中的物体很多变化是不能直接使用上一章讲到的线性变换的,因为游戏中会有大量的物体,这些物体的位置会经常变换,还有些物体初始位置可能就在原点,需要对其平移,那么在原点位置的物体平移操作线性变换无效,大量物体位置变换又会使得线性变换复杂且不直观。怎么解决这两个问题呢?因为线性变换的种种好处,我们又想用这种方法,那现在我们就去尝试推导一下,看能不能让能不能找到一种包含平移变换线性变换。 首先我们把旋转,缩放和平移分解为两种数学方法的联立,即对物体先线性变换,然后再用代数方法加上平移向量,写出公式为: 55ce6016a77a354b72483925d47ffa91.png  = Ar·As· d06307f0e20e6446097f05dd70526815.png + 80c5f93676edcd6164558568ab42969d.png 其中 P1 为变换的目标位置, P 为需要被变换的物体, Ar 是旋转变换矩阵, As 是缩放变换矩阵, 80c5f93676edcd6164558568ab42969d.png 是平移变换向量; fb7e66b29c4a3b83ae4e2dcbc387f9b3.png 图1 因为 Ar 和 As 可以相乘联立,即: A = Ar·As ,用 A 替换公式中得变换矩阵即: 55ce6016a77a354b72483925d47ffa91.png  = A· d06307f0e20e6446097f05dd70526815.png + 80c5f93676edcd6164558568ab42969d.png 用图来说明: 74e9561633f307e8df952bdbdb86e622.png 图2对物体进行线性变换 0fe808c39cb9e5d368f4fa2d4c0f0ea2.png 图3 对物体进行平移操作 下面我们会具体推导构建矩阵,使得构建矩阵包含上面的三种变换,所以就是纯数学得东东,如果不感兴趣的朋友可以直接跳过这部分得推导讲解。我们看看公式: 1eaa9b6de540cde40f890f34e8e324f4.png = A· d3bfe6a3418d5844a599cc28daeb7d20.png + 79fe9b484616e6aa6ceead0a00b2ff5f.png 是否能构建一个合适的矩阵把公式后面的加法运算包含进来呢?我们下面就尝试构建推导一下,从矩阵运算规律中我们知道 3c75dcee097c3343b0dd5d451ba6de45.png 我们仿照此公式,改造一下 A· d3bfe6a3418d5844a599cc28daeb7d20.png + 79fe9b484616e6aa6ceead0a00b2ff5f.png 为: eec4b56de7ac7486f547ebd6f2ce5fd4.png 我们观察一下这个结果,其中出现了 9401fc9aaf70cc59996eb0e4b6e7dee9.png ,如果我们 a610dda5a307a570cb71cffe622c62d9.png 变成 A· d3bfe6a3418d5844a599cc28daeb7d20.png + 79fe9b484616e6aa6ceead0a00b2ff5f.png 那么这个矩阵就出现了可以融合线性变换和代数运算的结果了 。 所以这里让 f771476a07876720a58e80df969a3b9e.png = 79fe9b484616e6aa6ceead0a00b2ff5f.png ,因为 79fe9b484616e6aa6ceead0a00b2ff5f.png 可能是一个非零得平移操作 , 所以 e4d4c2555261486c0ac276d5d8e10a50.png 和 k 都不能为零,故: e4d4c2555261486c0ac276d5d8e10a50.png = 79fe9b484616e6aa6ceead0a00b2ff5f.png /k。 这里我们可以看到构建的矩阵每次都需要 79fe9b484616e6aa6ceead0a00b2ff5f.png /k 这样一个除的操作,我们其实可以去掉这个操作,节省计算成本,所以 令k=1; 即: 118b56bac50b39c735b60030f5ef587a.png 再看矩阵下面的一行 4536fab9ad321cc0efd20b231cb70430.png ,这里因为 d3bfe6a3418d5844a599cc28daeb7d20.png 为变量,但这里构建的矩阵,我们是不想让这一行出现变量的,因为如果 ab3762e0a77f83920def56ca91e1b8c2.png 为变量,那么我们再次联立一个构建的矩阵的时候会改变结果值,比如: ea478fe1bc8cebd222b416d2d0fcafef.png · 3b4572ae6b31ffc96e6739eb8523b6a2.png = eb592e1404467016a39022dae70ff7f3.png 其中 4515f2406c2b38708555a3a4cc5a1626.png 为平移向量,B为线性变换矩阵 我们会发现 4536fab9ad321cc0efd20b231cb70430.png 也会出现在我们的结果中了,这是不能接受的,所以 4536fab9ad321cc0efd20b231cb70430.png 就必须为1。即: 4536fab9ad321cc0efd20b231cb70430.png = 1 ,这里因为 d3bfe6a3418d5844a599cc28daeb7d20.png 是变量(不同的点这个值时不一样的),所以 2f2220bc4b1286a3e4d55c15ea1eb82a.png 就必须为零,那 aaddaff4b7975640b17f51a1750b4bb5.png = 1. 故最后我们构建的矩阵就为: 74f6e3ac51ae677a83a0ad3441ccee54.png  · a1c67b1df86f78bf65cadd44d30521fb.pnga26451edce7c81ba1dcb86e031fdbad4.png 观察这个矩阵,其实质就是我们对原有的线性变换矩阵进行升维得操作,变成更高维度的矩阵来对物体进行线性变换,我们称这种高维度矩阵应用于低维度物体的线性变换为—— 放射变换。 二、仿射变换验证 我们验证一下仿射变换是否具有线性变换的优势,且可以把平移变换也包含进来,我们分别构建出旋转,缩放,和平移矩阵在二维空间中来验证计算一下: R1 = dd0aa1284f8a33aa82b5d48b1682e9bb.png为构建的旋转仿射矩阵  S1 = 26de31b3ab582647dbdda30d0af1db5b.png为构建的缩放仿射矩阵 T1 = 600c84bb90eaa83e73d7a407fd160077.png为构建的平移仿射矩阵 联立这些仿射矩阵得到最终结果仿射矩阵: At = T1·R1·S1= 600c84bb90eaa83e73d7a407fd160077.png·dd0aa1284f8a33aa82b5d48b1682e9bb.png·26de31b3ab582647dbdda30d0af1db5b.png=6e90408a4e5934b9d415216c53a140f7.png 假设改变d3bfe6a3418d5844a599cc28daeb7d20.png, At·a1c67b1df86f78bf65cadd44d30521fb.png = 6e90408a4e5934b9d415216c53a140f7.png·a1c67b1df86f78bf65cadd44d30521fb.png=ef417e3dd92bf6f06b44c081f1e625f2.png 我们可以看到最后的结果就是我们A·d3bfe6a3418d5844a599cc28daeb7d20.png + 79fe9b484616e6aa6ceead0a00b2ff5f.png的结果。 注意:矩阵的运算是不符合乘法得交换律得,我们上面的例子中,矩阵乘法顺序是:先进行旋转和缩放变换,然后再进行平移操作。如果先位移后旋转缩放,那得到结果会是不一样的,我们画图来说明一下: 三、齐次坐标

第一小节中对向量d3bfe6a3418d5844a599cc28daeb7d20.png的升维变换后a1c67b1df86f78bf65cadd44d30521fb.png的这种坐标称为齐次坐标,假设d3bfe6a3418d5844a599cc28daeb7d20.png = 37b401f47e13bafe6fa425201c4ed81b.png,那么a1c67b1df86f78bf65cadd44d30521fb.png = 26d9629e82115bff57eb18ef6aa8037a.png就是齐次坐标。在齐次坐标得概念中,n+1维上的值是不一定为1的,齐次坐标标准形式应该是这样的:如果有一个坐标是(X,Y,Z),它的其次坐标(x,y,z,w);那么他们的坐标值对应关系为:

X = x/w; Y = y/w; Z = z/w; 齐次坐标升维后n+1维w值是有用处得,用处有两个: 1、当w为0时,那么此点可以表示无限远,或者表示为向量。 2、透视变换(一种特殊的仿射变换)的时候,可以使得线性变换中不能相交的平行线相交。 第一个用处我们从对应关系中可以看到,但是第二个提到得透视变换是什么?平行线相交又是怎么回事?解释这个事情我们需要知道一个物体是怎么被绘制的,物体的绘制是需要一系列的变换最终会知道屏幕的,我们物体的变换过程:首先把一个物体变换到世界空间,然后从世界空间转换到相机空间,相机再进行透视投影变换,最后再变换到设备空间,绘制在屏幕上。这个过程中就会有透视变换,相机的透视变换其实就是在模拟人用眼看这个物体,距离眼睛越近的物体会越大,越远得物体就会被越小,在unity中相机这样的设置为透视相机就可以查看。 795958a8daafe094a17d3527df1e04c7.png 图4 相机设置为透视选项 相机所能看到得范围就为视锥体 40ab89c839c172054ac2fd15f973f888.png 图5 图中线框即为视锥体 我们可以看到视锥体是一个梯形空间,那么透视投影变换就是为了把视锥体内所有物体变换到一个单位立方体内 d632f1ea244eb4d5e8cb55c034a8dd14.png 图6 规范空间

我们对照图5和图6会发现透视变换后近处的物体相对被放大,远处的会相对被缩放,我们看看透视变换矩阵形式是这样的:

M =ca192b6861be805912e4ef3df5455062.png

我们看看这个矩阵被用来变换一个点后,点会是什么样的:

ca192b6861be805912e4ef3df5455062.png·26d9629e82115bff57eb18ef6aa8037a.png =b65fbeae074d11789e154379d23a74ad.png

实际得到的坐标为:

X = a·x/(d·z); Y = b·y/(d·z); Z = ( 2c0ddd6981ae99322651bd3dd230194a.png )/(d·z); 可以看出z越大,X和Y会越小,此时如果有平行线指向z方向,那么这个平行线就会逐渐相交。 0885e0ec8932678ba2951bd4d348bf9a.png 图7 图中左侧为长方形,右侧为透视变换后得结果,可以看到越远长方形两条边会越近,最终就会相交 四、总结 这章节中我们讲了线性变换是如何扩展为仿射变换,并应用于3D世界中得,我们推导了构建仿射变换的过程,并从算法上验证仿射变换的有效性,最后我们讲解齐次坐标及其好处,和一些透视变换的知识。透视变换等知识因不是本章得重点,所以并没有深入讲解,以后有时间了会给大家具体讲解。 下面的章节我们就要开始Shader得具体编写和原理讲解了,希望大家可以多多支持关注,如转载请标明来处,原创不易···谢谢
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值