任鸟飞FPS类型游戏绘制,骨骼,u3d,UE4和游戏安全,反外挂研究 (三)

书接上文,我们非矩阵的方式绘制 是没有那么的精确的
在学习矩阵之前,我们先来了解下绘制的几种方法

绘制的几种方法和反外挂建议
第一种 hook d3d/opengl
优点:不闪 ,代码简单
缺点:非常容易被检测
第二种 窗口上自行绘制,但是会闪
优缺点适中
第三种 自建透明窗口,覆盖游戏窗口,透明窗口上绘制
优点:稳定
确定:代码复杂,会闪
反外挂:无非就是针对外挂使用的函数进行检测

深入学习矩阵

对象的世界坐标列向量
x
y
z
w(w为了兼容4*4矩阵以及可以NDC坐标转化而设计存在的,大家可以暂且不管)
可以通过被一个游戏矩阵(以后我们就叫他游戏矩阵吧) 乘 从而获得 剪辑坐标,也可以叫裁剪坐标,都是翻译而来(暂且当成屏幕坐标也没问题,因为他到屏幕坐标转换及其简单)
在学习这个矩阵之前呢我们先来了解
行主序和列主序

行主序就是拿44矩阵的行来 后面的矩阵,我们前面的例子 都是这样
a1 a2 a3 a4 * x = a1 x+ a2y+ a3z + a4w
b1 b2 b3 b4 y b1 x+ b2y+ b3z + b4w
c1 c2 c3 c4 z c1 x+ c2y+ c3z + c4w
d1 d2 d3 d4 w d1 x+ d2y+ d3z + d4w

而列主序就是 拿44 矩阵的列 来 后面的矩阵,这个前面没有出现过
a1 b1 c1 d1 * x = a1 x+ a2y+ a3z + a4w
a2 b2 c2 d2 y b1 x+ b2y+ b3z + b4w
a3 b3 c3 d3 z c1 x+ c2y+ c3z + c4w
a4 b4 c4 d4 w d1 x+ d2y+ d3z + d4w

那么我们现在了解下这个游戏矩阵都能对我们干嘛,给他拆分成几个功能
最后他是这几个功能的结合体而已

缩放位移矩阵

如果是行主序矩阵的话就是

编辑
添加图片注释,不超过 140 字(可选)

扫描二维码关注公众号,回复: 14709198 查看本文章

(1不是固定的 应该写成Tw )
如果是列主序矩阵的话就是
Sx 0 0 0
0 Sy 0 0
0 0 Sz 0
Tx Ty Tz Tw


x
y
z
w
等于
xSx+wTx
ySy+wTy
zSz+wTz
w*Tw
对矩阵 x y z w 进行了 缩放和位移
所以我们在这里知道 矩阵移动影响的主要是
Tx Ty Tz Tw
结论一: 我们在走路做位移的情况下,行主序最后一列 列主序最后一行 Tx Ty Tz Tw 会改变
当然不一定只有走路的时候会变
原因很简单,这个矩阵是各种操作的结合体
如以下例子:
只改变Y的情况下

编辑
添加图片注释,不超过 140 字(可选)

只改变X的情况下

编辑
添加图片注释,不超过 140 字(可选)

只改变Z的情况下

编辑
添加图片注释,不超过 140 字(可选)

XYZ混合改变的情况下

编辑
添加图片注释,不超过 140 字(可选)

旋转矩阵

简单证明下结论

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

假设旋转45度

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

用极限验证法,验证结果正确

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

围绕Z轴 转动

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

结论二:只转动水平朝向的时候 行主序第三列不变 ,列主序第三行 不变化
列主序如下

编辑
添加图片注释,不超过 140 字(可选)

围绕X 轴转动

编辑
添加图片注释,不超过 140 字(可选)

结论三:只转动高低朝向的时候 行主序第一行不变 ,列主序第一列 不变化
列主序如下

编辑
添加图片注释,不超过 140 字(可选)

围绕Y 轴转动 我们没有这种情况的时候

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

开倍镜

编辑
添加图片注释,不超过 140 字(可选)

总结矩阵6条结论
第一结论: 行主序最后一列 列主序最后一行 走路 跳的状态会改变,不代表别的动作不改变
第二结论: 水平转动的情况 行主序第三列不变 列主序的话第三行不变
第三结论: 高低朝向改变的时候 行主序第一行不变 列主序的第一列不变
第四结论: 矩阵第一个值 -1 到1 的, 这个绝对吗 不绝对!
第五结论: 行主序 第一个行第3个元素 是固定的0 列主序 第一列的第三个元素是0 不绝对!
第六结论: 我们开倍镜 第一个值 会* 相应的倍数 不绝对!

编辑
添加图片注释,不超过 140 字(可选)

通过找到的矩阵可以进一步完善结论

通过以上的规律 CE 搜到如下矩阵地址
矩阵地址
hl.exe+1820100
这个过程文字很啰嗦,只能视频里见了,无非根据以上结论 扫描而已

世界坐标 ->剪辑坐标->NDC坐标->屏幕坐标

那么我们来了解下坐标的转换过程
通过以上的矩阵
世界坐标 ----> 剪辑坐标

a0 a1 a2 a 3

a4 a5 a6 a7

a8 a9 a10 a11

a12 a13 a14 a15

x
y
z
w

剪辑坐标 x = a0x +a4y + a8z + a12w
剪辑坐标 y = a1x +a5y + a9z + a13w
剪辑坐标 z = a2x +a6y + a10z + a14w
剪辑坐标 w = a3x +a7y + a11z + a15w

世界坐标按照我们之前的矩阵法则转换成了平面的剪辑坐标
但是剪辑坐标是和分辨率没有直接关系的 ,需要我们进一步转换

剪辑坐标坐标系如下 正中心为0,0

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

剪辑坐标---->NDC坐标

矩阵的设计中w 是可以让剪辑坐标范围到-1和1的 也就成了NDC坐标
所以NDC坐标很好理解,就是 -1到1的平面坐标系 中心点为0,0
NDC .x = 剪辑坐标 x/剪辑坐标 w
NDC.y =剪辑坐标y/剪辑坐标 w
NDC.z =剪辑坐标z/剪辑坐标 w

DNC坐标---->屏幕坐标

有了DNC坐标我们可以很容易转换成屏幕坐标了
当然屏幕坐标不止一种形式
我们现在只以CS为例
后面会有其他类型

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

DNC.x / 1 = 屏幕坐标差.x / 分辨率_宽 /2
屏幕坐标差.x = (分辨率_宽 /2) * DNC.x
屏幕坐标.x = (分辨率_宽 /2) * DNC.x + 分辨率_宽/2

DNC.y / 1 = 屏幕坐标差.y / 分辨率_高 /2
屏幕坐标差.y = -(分辨率_高 /2)*DNC.y
屏幕坐标.y= -(分辨率_高 /2)*DNC.y + 分辨率_高 /2

矩阵绘制

最终代码如下
再用之前的代码 只把世界坐标转屏幕坐标_非矩阵() 改成世界坐标转屏幕坐标() 就可以实现功能了
其实也是我们之前的代码设计的比较合理
这样 只要替换一句命令,其他指令完全不影响

bool 绘制::世界坐标转屏幕坐标(坐标结构_3 游戏坐标,坐标结构_2& 屏幕坐标)
{
取窗口信息();
memcpy(&m_矩阵, (PBYTE*)m_矩阵地址, sizeof(m_矩阵));
坐标结构_4 裁剪坐标;
裁剪坐标.x = 游戏坐标.x * m_矩阵[0] + 游戏坐标.y * m_矩阵[4] + 游戏坐标.z * m_矩阵[8] + m_矩阵[12];
裁剪坐标.y = 游戏坐标.x * m_矩阵[1] + 游戏坐标.y * m_矩阵[5] + 游戏坐标.z * m_矩阵[9] + m_矩阵[13];
裁剪坐标.z = 游戏坐标.x * m_矩阵[2] + 游戏坐标.y * m_矩阵[6] + 游戏坐标.z * m_矩阵[10] + m_矩阵[14];
裁剪坐标.w = 游戏坐标.x * m_矩阵[3] + 游戏坐标.y * m_矩阵[7] + 游戏坐标.z * m_矩阵[11] + m_矩阵[15];

if (裁剪坐标.w < 0.0f)
{
    return false;
}

坐标结构_3 NDC;
NDC.x = 裁剪坐标.x / 裁剪坐标.w;
NDC.y = 裁剪坐标.y / 裁剪坐标.w;
NDC.z = 裁剪坐标.z / 裁剪坐标.w;

屏幕坐标.x = (m_分辨率宽 / 2) * NDC.x + m_分辨率宽 / 2;
屏幕坐标.y = -(m_分辨率高 / 2) * NDC.y + m_分辨率高 / 2;

return true;

}

编辑

切换为居中
添加图片注释,不超过 140 字(可选)

这次不用微调就已经 精确了吧?
所以证明矩阵确实算的比较准确而且帮我们省掉了大量计算的时间

到这里,你的基础算过了
迎接后面真正的学习吧!

参考视频:链接: https://pan.baidu.com/s/1dN63zxgQECeeH1lzQ1P9cg 提取码: dgs9

猜你喜欢

转载自blog.csdn.net/qq_43355637/article/details/122499891