zhouqijie

概述 蒙皮及矩阵调色板

把三维网格顶点联系至骨骼的过程,称为蒙皮(skinning)

第一部分 逐顶点蒙皮信息

每个顶点可以绑定至一个或者多个关节。如果只绑定至一个关节,它就会完全跟随关节移动。如果绑定至多个关节,就会取逐一绑定至关节后的位置的加权平均

  1. 关节索引。
  2. 权重因子。(所有权重因子之和为1)

通常游戏引擎会限制每个顶点能绑定的关节数目。典型的限制为每顶点4个关节,因为4个8位索引能方便地打包为一个32位,并且关节数超过4个多数人也不能再分辨质量差别。

因为关节权重之和为1,所以最后一个权重可以略去,运行时可以用1做差求得。

struct SkinnedVertex
{
    vec3 pos;
    vec3 normal;
    vec2 texcoord;
    uint8 jointIndex[4];
    float jointWeight[3];
}

第二部分 蒙皮矩阵

蒙皮网格顶点会追随其绑定的关节而移动,数学实现方法就是蒙皮矩阵(skinning matrix)

蒙皮矩阵比较特殊,它不是基变换矩阵。顶点变换前后都在模型空间,只是从绑定姿势的模型空间变换到当前姿势的模型空间。

1.特例-单个顶点蒙皮至单个关节的骨骼

推导蒙皮矩阵时一个关键已知条件–顶点绑定至关节的位置时,在该关节空间的位置是不变的。

我们可以把顶点于模型空间的绑定姿势位置转换至关节空间,再把关节移至当前姿势,最后把顶点转回模型空间。

所以计算蒙皮矩阵:$M_{skinning} = M_{currentJoint->model} · (M_{bindJoint -> model}) ^ {-1}$

绑定姿势的矩阵是不变的,存储其逆矩阵作为常量,不需要运行时计算。

$Vertex_{ModelSpaceCurrent} = M_{skinning} · Vertex_{ModelSpaceBind}$。

2.扩展-多个关节的骨骼

如果骨骼含有多个关节应该注意:

  1. 矩阵$M_{currentJoint -> model}$和$M_{bindJoint->model}$可以使用矩阵连乘正确求得。
  2. 我们必须计算一组蒙皮矩阵,每个矩阵对于一个关节,称为矩阵调色盘(matrix palette)。当渲染一个蒙皮网格时,调色盘便要传送至渲染引擎供渲染器查找。

3.扩展-顶点蒙皮至多个关节

要把顶点蒙皮至多个关节,我们可以计算顶点分别蒙皮至每个关节,产生对于每个关节的模型空间位置,然后把这些结果进行加权平均来求出最终位置。

补充:模型至世界变换

每个顶点最终都会由模型空间变换至世界空间。因此有些引擎会把蒙皮矩阵调色板预先乘以模型世界变换,但有些引擎不会这么做,视情况而定。

Jason:有些情况例如动画Instancing就不能预先乘以模型世界矩阵,因为需要把单个调色板用于所有的角色动画。