到目前为止,我对这些空间的理解是,它们定义了游戏的某个方面。 3d世界。视图空间实际上只是摄影机,我们通过创建一个矩阵来定义它,该矩阵包含摄像机位置,摄像机目标和" up"相机的方向。
这些都是在代码中完成的,如下所示......
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世界)
有人可以向我解释这里究竟发生了什么
答案 0 :(得分:1)
第一个建议:由于您对DirectXMath和Direct3D完全不熟悉,因此您应该特别关注DirectX Tool Kit和SimpleMath包装器。它会为你节省很多精力。
渲染对象时,实际上只有一个转换。它从定义的任何坐标系中获取对象(称为“局部”或“模型”坐标空间),最终结果为x,y
像素位置和z
深度。
然而,对于人类而言,通常更容易将这种转变视为分阶段发生 - 事实上,由于同质坐标的力量和通过乘法的连接,它实际上只是一个向量矩阵的乘法。这通常被认为是world -> view -> projection
。
XMMatrixTranslation
,XMMatrixRototation*
和XMMatrixScaling
函数组合在一起创建的(并且还有许多其他方法可以在库中创建转换矩阵,包括使用四元数旋转)。XMMatrixPerspectiveFovLH
,XMMatrixOrthographicLH
相关函数完成的。RE:Handedness
“左撇子”与“右撇子”观看系统的选择完全取决于品味和内容的定义。历史上,Direct3D使用左手坐标,而OpenGL使用右手坐标。在现代可编程着色器中,系统内置的任何东西都没有关注。你必须保持一致。 XNA Game Studio和SimpleMath使用“右手”系统。 99%的案例中的DirectXMath都使用。
答案 1 :(得分:0)
将对象转换为"查看空间"基本上是根据相机的位置和方向/旋转重新定位相机。
视图或相机矩阵本身是使用相机的参考框架制作的:想象一下x,y和z矢量从相机出来,跟随相机的任何旋转,这样它们总是从相机中出来& #39; s top,right和front。它们通常分别称为向上,向右和视图向量。
视图向量是使用查看点和位置导出的,即
view vector = lookAt - Position。
然后使用新计算的视图矢量和您提供的向上矢量的叉积创建相机的右矢量。
右向量=视图向量X向量
然后最终"真实"使用新视图和右向量创建摄像机向上
向上矢量=右向量X视图向量
作为一个非常重要的注意事项,您需要确保三个向量是正交归一化的。这听起来非常技术性,但只是意味着所有三个都具有一个长度并且彼此真正成90度,或者有趣的东西可能发生在拉伸和扭曲等模型上。
如何在视图矩阵中使用这些向量是为了创建矩阵的左上角3 x 3部分。然后,根据您是使用行向量还是向量向量,最底部的行或最右侧的列使用摄像机的位置。
现在,真正的诀窍是存储的值实际上是位置/旋转的INVERSE。想一想。如果你有一个摄像头并将其向右移动到位置(2,0,0),则必须将所有对象-2.0向左翻转,以获得移动摄像头所期望的效果。同样对于旋转 - 向右旋转摄像机,对象应相对于摄像机向左移动
因此,对于位于(4,5,3)并且未旋转的相机,使用视图矩阵中的列向量应如下所示:
[1 0 0 -4]
[0 1 0 -5]
[0 0 1 -3]
[0 0 0 1]
正如Chuck Walbourn所说,很多时候,许多物体的变换是使用从世界,视角,投影矩阵产生的矩阵的一次乘法,但是在某些情况下你会想要使用视角空间。根据您的方法,在照明设备中使用模型视图矩阵(无投影)。