UP | HOME

Game Engine Architecture

Table of Contents

Game Engine Architecture 读书笔记
<!– more –>

第一部分 Foundations

第二部分 Low-Level Engine Systems

第三部分 Graphics and Motion

Rendering Engine

Animation Systems

Types of Character Animation

Cel Animation
Rigid Hierarchical Animation
Per-Vertex Animation and Morph Targets
Skinned Animation

Skeletons

骨骼系统是有一些列有层次结构的关节组成的。我们经常混用骨骼 和 关节这两个专业术语。但是,骨骼这个术语其实是错误用法。技术上讲关节是动画直接操纵的对象,而骨骼只是关节之间的空白区域。

Skeleton Hierarchy
Representing a Skeleton in Memory

Poses

Bind Pose

Bind Pose 又被称为 参考姿势 或 重置姿势。该姿势是 3D 模型在绑定到骨骼之前的姿势。
Bind Pose 也被称为 T 姿势,因为角色会把脚轻微地分开站着,并且双臂向外伸展呈 T 字形。之所以选择这个特殊的姿势,是因为该姿势将身体的各个肢体彼此分开,可以让绑定顶点到关节的过程更容易些。

Local Pose

一个关节的姿势通常特定地关联到它的父关节。父子结构的姿势允许一个关节自然地移动,例如,旋转肩关节时,保持肘、手腕、手指的姿势保持不变,整个手臂会按照肩关节旋转。
一个关节的局部姿势:

\begin{align} & \quad P_j = \begin{bmatrix} S_jR_j & 0 \\ T_j & 1 \end{bmatrix}\nonumber \\ \end{align}

整个骨架的局部姿势:

\begin{align} P^{skel}=\{P_j\}|_{j=0}^{N-1} \end{align}
Global Pose

有时候将关节姿势表示为模型空间或世界空间会很方便。此时,关节姿势被称为全局姿势。
关节根节点的父节点坐标空间被定义为模型空间。
通常,任何一个关节的全局姿势可以表示为: \(P_{j \to M} = \prod_{i=j}^{0}P_{i \to p(i)}\)
例如: \(P_{5 \to M} = P_{5 \to 4}P_{4 \to 3}P_{3 \to 0}P_{0 \to M}\)

Clips

The Local Time Line

Skinning and Matrix Palette Generation

任何骨架姿势都可以表示为一组局部或全局的关节姿势变换。下面我们将探索将 3DMesh 上的顶点附加到一个骨架姿势上的过程,这个过程就是蒙皮。

Per-Vertex Skinning Information

将网格的顶点关联到骨骼就是蒙皮网格。
将网格蒙皮到骨骼时,必须为每个顶点提供额外的信息:

  • 顶点所关联的关节的索引
  • 顶点对每个所关联的关节的权重值为多少
  struct SkinnedVertex
  {
      float m_position[3]; // (Px, Py, Pz)
      float m_normal[3]; // (Nx, Ny, Nz)
      float m_u, m_v; // texture coordinates (u, v)
      U8 m_jointIndex[4]; // joint indices
      float m_jointWeight[3]; // joint weights, last one omitted
  }
The Mathematics of Skinning

蒙皮矩阵是将蒙皮网格的顶点从原来的位置(绑定姿势)变换至骨骼的当前姿势的矩阵

对于单个关节骨骼求解蒙皮矩阵
  • \(V_j\) 为在关节 j 空间下表示的顶点坐标
  • \(V_{B}^{M}\) 为在模型空间下表示的绑定姿势的顶点坐标
  • \(V_{C}^{M}\) 为在模型空间下表示的当前姿势的顶点坐标
  • \(B_{j \to M}\) 绑定姿势下,将关节 j 空间坐标转化为模型空间坐标的矩阵
  • \(B_{M \to j}\) 绑定姿势下,将模型空间坐标转化为关节 j 空间坐标的矩阵
  • \(C_{j \to M}\) 表示当前姿势,将关节 j 空间坐标转化为模型空间坐标的矩阵
\begin{align} & \quad V_j = V_{B}^{M}B_{M \to j} = V_{B}^{M}(B_{j \to M})^{-1} \nonumber \\ & \quad V_{C}^{M} = V_jC_{j \to M} \nonumber \\ & \quad V_{C}^{M} = V_jC_{j \to M} \nonumber \\ & \quad = V_{B}^{M}(B_{j \to M})^{-1}C_{j \to M} \nonumber \\ & \quad = V_{B}^{M}K_j \nonumber \\ & \quad K_j = (B_{j \to M})^{-1}C_{j \to M} \nonumber \\ \end{align}

上面的 \(K_j\) 就是蒙皮矩阵

对于多个关节骨骼求解蒙皮矩阵
  • \(P_{j \to p(j)}\) 为关节 j 的当前局部姿势
\begin{align} & \quad P_{j \to M} = \prod_{i=j}^{0}P_{i \to p(j)} \nonumber \\ & \quad K_j = (B_{j \to M})^{-1}P_{j \to M} \nonumber \\ \end{align}

动画引擎通常为每个关节计算局部姿势( \(C{j \to p(j)}\) ),然后使用

Animation Blending

动画混合是指令一个以上的动画片段对角色最终姿势起作用的技术。混合是把两个或更多的输入姿势结合,产生骨骼的输出姿势。

动画混合可以是同一时间点,两个或两个以上姿势的混合。例如,通过混合负伤和没负伤的步行动画,可以产生不同负伤程度的步行动画。
也可以是不同时间点的两个已知姿势间的混合。例如,动画关键帧之间的采样;又例如不同片段之间的过渡;

LERP Blending

Collision And Rigid Body Dynamics

第四部分 Gameplay Systems