15

所以,距离我写这个问题已经有几个月了,从那以后我玩弄了“原始”C++ D3D、Ogre 和 Irrlicht 图形引擎以及最近的 Microsoft XNA。我已经制作了一些 2D 游戏(主要是俄罗斯方块、小行星等旧东西的复制品),并在上述技术中向 3D 世界迈出了一些(非常)小步。

创建实际的游戏逻辑、抽象出对象交互以允许我插入不同形式的控制(计算机、播放器、网络等)、执行线程或我使用的任何其他东西时,我几乎没有问题从我的日常工作开始——这对我来说感觉非常自然。我很少使用 HLSL 和粒子效果(非常非常基础)。

但是涉及矩阵和向量的 3D 数学(以及 Ogre3D 中的四元数(?),这些真的需要吗?)......真的让我明白,我可以遵循示例(例如,我从 O'Reilly 购买的 Learning XNA 3.0 书,这是一本很棒的书顺便说一句),我理解示例中发生某些事情的原因方式,但是当我尝试自己做某事时,我觉得我缺乏对这种数学的理解,无法真正理解并使其工作我。

所以我正在寻找学习 3D 数学(主要是)和一些着色器/粒子效果书籍的资源。我更喜欢教育性的资源,并且比诸如向量数学的医生论文之类的东西要慢一点,这将超出我的想象。理想的资源应该是在 D3D 中展示这一切的东西。

4

5 回答 5

24

好的,矩阵/向量计算的快速课程:

矩阵是在矩形网格中排序的数字集合,例如:

[ 0,  1,  2 ]
[ 2,  3,  5 ]
[ 2,  1,  3 ]
[ 0,  0,  1 ]

上述矩阵有 4 行 3 列,因此是一个 4 x 3 矩阵。向量是具有 1 行(行向量)或 1 列(列向量)的矩阵。正态数称为标量以与矩阵进行对比。

矩阵使用大写字母,标量使用小写字母也很常见。

我们可以用矩阵进行基本计算,但有一些条件。

添加

如果矩阵具有相同的维度,则可以添加矩阵。因此,2x2 矩阵可以添加到 2x2 矩阵,但不能添加到 3x5 矩阵。

[ 1,  2 ] + [ 2,  5 ] = [ 3,  7 ]
[ 2,  4 ]   [ 0,  3 ]   [ 2,  7 ]

您会看到,通过添加每个单元格中的每个数字,都会将其添加到另一个矩阵中相同位置的数字上。

矩阵乘法

矩阵可以相乘,但这有点复杂。为了将矩阵 A 与矩阵 B 相乘,您需要将矩阵 A 中的每一行中的数字与矩阵 B 中的每一列相乘。这意味着如果将 axb 矩阵与 acxd 矩阵相乘,则 b 和 c 必须相等,并且结果矩阵为 axd:

[1,2,3] x [4,6] = [1x4+2x2+3x2, 1x6+2x1+3x3 ] = [4+4+6,  6+2+9  ] = [14, 20]
[1,4,5]   [2,1]   [1x4+4x2+5x2, 1x6+4x1+5x3 ]   [4+8+10, 6+4+15 ]   [22, 25]
          [2,3] 

如您所见,对于矩阵,A x B 不同于 B x A。

矩阵标量乘法

您可以将矩阵与标量相乘。在这种情况下,每个单元格都乘以该数字:

3 x [1,2] = [ 3, 6]
    [4,7]   [12,21]

反转矩阵 矩阵除法是不可能的,但您可以创建一个矩阵的反转,使得 A x A-inv 是一个除主对角线外全为零的矩阵:

[ 1, 0, 0 ]
[ 0, 1, 0 ]
[ 0, 0, 1 ]

矩阵求逆只能用方阵来完成,这是一项复杂的工作,不一定有结果。

从矩阵 A 开始:

    [ 1, 2, 3 ]
A = [ 1, 3, 4 ]
    [ 2, 5, 1 ]

我们添加 3 个额外的列并用单位矩阵填充它们:

[ 1, 2, 3, 1, 0, 0 ]
[ 1, 3, 4, 0, 1, 0 ]
[ 2, 5, 1, 0, 0, 1 ]

现在我们从第一列开始。我们需要从每一行中减去第一行,使得第一列除了第一行之外只包含零。为了做到这一点,我们从第二行中减去第一行一次,从第三行中减去两次:

[ 1, 2, 3, 1, 0, 0 ]
[ 0, 1, 1,-1, 1, 0 ]
[ 0, 1,-5,-2, 0, 1 ]

现在我们对第二列重复此操作(第一行两次,第三行一次)

[ 1, 0, 1, 3,-2, 0 ]
[ 0, 1, 1,-1, 1, 0 ]
[ 0, 0,-6,-1,-1, 1 ]

对于第三列,我们有一个小问题。枢轴数是 -6 而不是 1。但我们可以通过将整行乘以 -1/6 来解决这个问题:

[ 1, 0, 1,   3,  -2,    0 ]
[ 0, 1, 1,  -1,   1,    0 ]
[ 0, 0, 1, 1/6, 1/6, -1/6 ]

现在我们可以从第一行和第二行中减去第三行:

[ 1, 0, 0, 17/6,-13/6,  1/6 ]
[ 0, 1, 0, -7/6,  5/6,  1/6 ]
[ 0, 0, 1,  1/6,  1/6, -1/6 ]

好的,现在我们有了 A 的倒数:

[ 17/6,-13/6,  1/6 ]
[ -7/6,  5/6,  1/6 ]
[  1/6,  1/6, -1/6 ]

我们可以这样写:

      [ 17,-13,  1 ]
1/6 * [ -7,  5,  1 ]
      [  1,  1, -1 ]



    [ 1, 2, 3 ]   [ 17,-13,  1 ]                [ 6, 0, 0 ]    [ 1, 0, 0 ]
A = [ 1, 3, 4 ] x [ -7,  5,  1 ] x 1/6  = 1/6 x [ 0, 6, 0 ] =  [ 0, 1, 0 ]
    [ 2, 5, 1 ]   [  1,  1, -1 ]                [ 0, 0, 6 ]    [ 0, 0, 1 ]

希望这个对你有帮助。

于 2009-01-28T12:45:52.757 回答
9

Fredrik - 简短的回答是,是的,您必须学习矩阵和向量,因为它们是 3D 工作的数学基础。

虽然线性代数绝对不是博士水平的数学,但它需要一些工作。要开始使用,请在亚马逊上查看这本书:它看起来正是您正在寻找的。我没有读过这本特别的书(我在研究生院使用的那本书有点过时了),但它的评价特别好。

另一件事:市场上有各种 3D 建模引擎可以为您完成这项工作。其中最著名的可以说是 Valve 的Source Engine。您可以使用这个引擎(专为 HalfLife2 和 CounterStrike 构建)来创建一些非常复杂的游戏,同时工作在 3D 建模级别之上。事实上,作为 Steam 网络上最受欢迎的游戏之一,Garry 的 mod开始时有人只是在玩一些你可以用 Steam 引擎做的很酷的事情。这是一个站点的链接,该站点提供了使用 Source Engine 构建自己的世界的教程,以防您感兴趣。

于 2009-01-28T12:37:48.017 回答
4

你肯定需要学习线性代数。麻省理工学院在 youtube 上免费发布了整个课程。你可以从这里开始。没那么难,相信我!玩得开心 ;)

于 2009-02-02T22:16:26.997 回答
2

计算机图形应用数学”是一本入门级教科书,采用适合课堂的方法来学习 3D 编程需要熟悉的所有基本数学(主要是矩阵和向量)

还有关于四元数的说明:它们对某些应用非常有用。SLERP(球面线性插值)可以非常方便地制作平滑/吸引人的相机运动(除其他外)。SLERP 对于矩阵来说是一种痛苦(昂贵),但对于四元数来说既便宜又容易。学会使用并爱上它们——即使你不完全理解它们。

于 2009-02-02T22:02:47.273 回答
1

特别是对于向量,线性代数的介绍性文本或课程应该能够让您很快上手。

于 2009-01-28T12:04:47.207 回答