为 DirectX9 使用 C++ 代理 dll,如何旋转场景?

Using a C++ proxy dll for DirectX9, how would one rotate a scene?

我希望通过代理 d3d9.dll 为 DirectX 9 游戏添加自由外观(即使游戏禁用它)。我有 C++ 中简单代理的源代码。游戏本身不开源,但开发者对模组毫不在意。

我知道这是可能的,因为一些使用代理 dll 的 3D anaglpyh 驱动程序 hack(如 IZ3D)在两只眼睛之间的距离设置得非常高时会旋转场景。网络上这种效果的代码(至少,使用 Google)根本不存在。请记住,该游戏使用着色器并且没有明显使用矩阵堆栈。

我该怎么做?

一般来说,大多数 3D 着色器使用一组三个矩阵来确定如何将顶点转换为屏幕 space。在 DirectX 中,这些通常称为世界、视图和投影矩阵(在 GL 中,'World' 矩阵通常称为 'Model')。在 D3D9 中,这些矩阵将被设置为着色器常量(通过 IDirect3DDevice9::SetVertexShaderConstantF)。另请注意,在将这些矩阵传递给顶点着色器之前,将这些矩阵连接到 CPU 上的单个矩阵是一种常见的做法,这样就不会对每个顶点执行冗余计算。

假设这是您尝试代理的游戏中着色器的设置,您需要确定要定位的着色器(例如,哪些是 3D 世界对象着色器)。请注意,游戏中可能存在不适用于 3D 世界渲染的着色器,例如 UI(如果适用)。然后,在目标着色器处于活动状态时拦截对 IDirect3DDevice9::SetVertexShaderConstantF 的任何调用,并修改与将顶点转换为屏幕 space 相关联的制服。这将需要一些试验和错误,当然,还需要一些 HLSL 反汇编知识,因为我假设您没有着色器的源代码。

即使做到了这一点,如果您打算以任何重要方式修改转换的 'View' 部分(例如,相机所注视的位置),您很可能得不到想要的结果.原因是许多游戏系统经常在 CPU 上执行 3D 世界计算,这显然不会受到影响。最明显的例子是基于视锥体的剔除系统,它决定渲染哪些对象。因为代理不会修改这样的系统,所以你可以 "look off into empty space".