pj66666666 发表于 2021-12-12 19:26

FPS游戏利用矩阵实现透视,以单机版csgo为例,附源码,有详细注释。

网上现在有很多FPS方框透视教程,但是很多都是找到矩阵,用个易语言模块就实现了,但是这样我们局限性很大,没有模块的时候该怎么办?
而且易语言的模块都看不到源码,所以我写了本篇文章说一下具体实现透视的算法,和大致的原理。
这个算法需要一点数学基础,与线性代数有关。 只要你不问我一个三行四列的行列式怎么算 ,你应该就可以看的懂。
我们取得矩阵的目的是什么呢,就是将人物的世界坐标转换为我们的屏幕坐标。
也就是将一个三维向量转为二维向量,这时候我们就需要矩阵的乘法来转换。
向量顾名思义就是既有方向又有大小的量。二维坐标系上的向量就是二维向量,如(2,3) 三维坐标系上的向量就是三维向量如(3,4,5)。

我们也可以这样写,这是一个列向量,也是一个矩阵。
一个游戏中一很多的坐标系如 世界坐标系 物体坐标系 观察坐标系等等。我们屏幕上显示物体的坐标x,y坐标就是通过世界坐标系中的坐标乘一个混合矩阵得到的。
这其中的数学原理我就不细讲了,因为这是做3d游戏需要学习的一些数学知识,想了解详情的可以参考知乎一篇文章:矩阵变换坐标系 深入理解 - 知乎 (zhihu.com)
我就举两个小例子,一个坐标系到另外一个坐标系 是通过平移,旋转和缩放实现的。


矩阵的乘法运算:



我这样写应该很容易理解,比百度百科上那些概念公式更容易看的懂。
比如我们将一个单位矩阵这个位置填上x,y,z坐标


做如下乘法

就相当于我们做了将(0,0,0)平移到了(x,y,z)

如果乘一个这样的矩阵呢



就完成了对z的缩放

这时候,你应该大致能理解为什么要乘以矩阵了,接下来我们用算法实现一下,世界坐标到屏幕坐标


这里我们找到的是竖矩阵,也就是这样的。因为我们游戏是directX的 如果是openGL可能就是横矩阵 ,那我们的算法就要变,但是很简单,只要举一反三就可以了



我们应该用矩阵乘世界坐标而不是世界坐标乘矩阵
因为矩阵的乘法只能是Anm*Bmj这样的也就是说前面矩阵的列数必须等于后面矩阵的行数,乘完我们就得到一个 n行j列的矩阵,也就是说矩阵的乘法不满足乘法交换率。


    vec clipCoords;
    clipCoords.x = pos.x * matrix + pos.y * matrix + pos.z * matrix + matrix;
    clipCoords.y = pos.x * matrix + pos.y * matrix + pos.z * matrix + matrix;
    clipCoords.z = pos.x * matrix + pos.y * matrix + pos.z * matrix + matrix;
    clipCoords.w = pos.x * matrix + pos.y * matrix + pos.z * matrix + matrix;
我们这样乘完得到的是一个裁剪坐标

接着我们转换为DNC坐标,也就是标准化设备坐标
    vec NDC;
    NDC.x = clipCoords.x / clipCoords.w;
    NDC.y = clipCoords.y / clipCoords.w;
    NDC.z = clipCoords.z / clipCoords.w;、

为什么这样算呢 ,这不是我说的,是微软的文档说的,这些东西就是那些计算机图形学的知识了 ,可以知其然不知其所以然,但是不能完全不知道用别的写好的模块,我们需要自己会用。

下一步就是转换为屏幕坐标,一样也是文档里可以查阅到的公式,就是利用屏幕的宽和高进行一些计算,就得到了屏幕坐标。
    screen.x = (windowWidth / 2 * NDC.x) + (NDC.x + windowWidth / 2);
    screen.y = -(windowHeight / 2 * NDC.y) + (NDC.y + windowHeight / 2);

我们得到的这个坐标是人物脚下正中心的坐标,如果需要画方框我们需要找到头部坐标,把人物的身高算出来,画出完美大小的方框。
我这里就进行测试一下



可以看到坐标还是比较准确的


无论我们是在什么位置,都能在敌人的脚下画出我输入的文本。

我们需要找的数据也很少,其他的数据我就不说了 ,很好找。

我大致说一下矩阵的几个特点:
还是以我们找到的这个竖矩阵为例

1.


这个值的绝对值小于2
除非在狙击枪开镜的时候会大于2

2.

这几个值基本一样

3.


这大概率有个0.00

我们鼠标晃动的时候矩阵就会变,但是如果只移动人物 鼠标不动,就只有最后一列的值变动。
通过这些慢慢搜索出矩阵就可以了。
源码在附件





昔逢丶 发表于 2021-12-13 22:12

内容很好就是比较费号

那一年的白洁啊 发表于 2021-12-14 09:50

一个三行四列的行列式怎么算?

engeng2 发表于 2021-12-13 11:28

原来是这样的原理,学习了!

fastst 发表于 2021-12-13 12:43

感谢分享经验,看着挺复杂的

GTK+ 发表于 2021-12-13 16:45

厉害了,感谢分享

AndyJMR 发表于 2021-12-13 17:33

学以致用:lol

GJH588 发表于 2021-12-13 18:31

关于矩阵我记得大学课程有系统化的讲解,不过很多写这些游戏辅助的人来说,他们不需要知道的这么详细,因为太多人只想得到成果,根本不会去看过程和细节{:301_1001:}

七度空间 发表于 2021-12-13 19:33

感谢分享经验

Noth1ng 发表于 2021-12-13 19:39

这会了不就牛比了吗

咔c君 发表于 2021-12-13 22:48

学习了不错
页: [1] 2 3 4 5 6 7
查看完整版本: FPS游戏利用矩阵实现透视,以单机版csgo为例,附源码,有详细注释。