c++ - 我需要对 "Spaces"(世界空间、 View 空间、投影空间、局部空间和屏幕空间)的概念进行一些澄清(c++、direct3d 11)

标签 c++ direct3d11

到目前为止,我对这些空间的理解是它们定义了游戏 3d 世界的某个方面。 View 空间实际上就是相机,我们通过创建一个包含相机位置、相机目标和相机“向上”方向的矩阵来定义它。

这一切都是在代码中完成的,如下...

XMMATRIX CameraView;
XMVECTOR CameraPosition;                        
XMVECTOR CameraTarget;
XMVECTOR CameraUp;

/* Describing the matrix */
CameraPosition = XMVectorSet(0.0f, 0.0f, -0.5f, 0.0f);      
CameraTarget = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);         
CameraUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);

/*  Creating the matrix*/
CameraView = XMMatrixLookAtLH(CameraPosition, CameraTarget, CameraUp);  

我很难在脑海中想象这一点。所以简单来说.. 我只是通过创建 CameraView 来“允许”玩家随意移动吗? (假设 3d 世界已经创建)

谁能给我解释一下这里究竟发生了什么

最佳答案

第一个建议:由于您是 DirectXMath 和 Direct3D 的新手,您应该看看 DirectX Tool KitSimpleMath特别是 wrapper 。它会让你在这里分心很多。

当您渲染一个对象时,实际上只进行了一次转换。它从它定义的任何坐标系(称为“本地”或“模型”坐标空间)获取对象,最终结果是一个 x,y 像素位置和一个 z深度。

然而,对于人类来说,通常更容易认为这种转换是分阶段发生的——实际上,由于齐次坐标的强大功能和通过乘法连接,它实际上只是一个 vector 矩阵乘法。这通常被认为是 world -> view -> projection

  1. “世界”矩阵将本地坐标中定义的点放置到“世界”坐标中。这允许所有模型都在它们自己的本地坐标中,然后相对于另一个放置在场景中。世界坐标系也是您规范地定义光源所在位置的地方。这通常是通过将 XMMatrixTranslationXMMatrixRototation*XMMatrixScaling 函数相乘来创建的(还有许多其他方法可以创建转换矩阵以及库中的内容,包括使用四元数进行旋转)。
  2. “ View ”矩阵将世界坐标空间中的点移动到 View 坐标空间中,这通常被认为是相机如何看待事物。这就是您显示的代码片段正在计算的内容。给定世界坐标中的相机位置,世界坐标中的相机目标位置,以及任意“向上” vector ,该函数使用“左手”观察坐标计算“ View ”矩阵需要的内容(因此“LH ").
  3. “投影”矩阵将点从 View 系统移动到定义“投影”的通用规范化框,包括应用透视投影或正交投影。对于 DirectXMath,这是通过 XMMatrixPerspectiveFovLHXMMatrixOrthographicLH 和相关函数完成的。

参见 3D projection

回复:惯用手

“左撇子”与“右撇子”观看系统的选择纯粹是品味问题以及如何定义您的内容。历史上,Direct3D 使用左手坐标,而 OpenGL 使用右手坐标。在现代可编程着色器中,系统中没有内置任何东西。你只需要保持一致。 XNA Game Studio 和 SimpleMath 使用“右手”系统。 DirectXMath 在 99% 的情况下都使用其中之一。

参见 Right-hand rule

关于c++ - 我需要对 "Spaces"(世界空间、 View 空间、投影空间、局部空间和屏幕空间)的概念进行一些澄清(c++、direct3d 11),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31467619/

相关文章:

c++ - 是否有可能通过使用 openMP 在 fstream(文件读取)上获得一些性能提升

c++ - 结构和数组( ‘Array’ 的初始值设定项太多)C++

c++ - 编译时检查模板类型 C++

c++ - 常量表达式类型定义

c++ - 开始 Direct3D,简单三角形不渲染

c++ - 在 hlsl 着色器中设置全局参数的正确方法是什么?

c++ - Direct2D 实际上可以与 direct3D 11 设备一起使用吗?

c++ - 原子赋值运算符

malloc - 常量缓冲区的aligned_malloc() 与alignas()