设置次级控制器一直以来是很多rigger讨论的话题,从2年前明白了该技术的核心原理后,我看了很多帖子的讨论都集中在用什么去让次级控制跟随,例如:follicle,rivet,pointEmitter等等,但没有看到一个帖子将核心内容进行分享,这里将核心原理跟大家分享讨论下。
回溯次级控制器的资料,无疑是某年masterClass的设置文件 cat_face_final_merge.ma
如下图:
这文件中使簇跟随的方法就是rivet,很多人被误导认为,revet + cluster 就是次级控制器的核心技术,
这个误导了很多人很长段时间。
其实,次级控制器的关键是要解决双倍变形问题。那么我们需要使次级控制器跟随模型表面移动时不产生任何变形,那么我们需要知道怎么使骨骼或簇的父物体移动,变形却不产生,这就需要了解其变形的公式,本文中以较为复杂的skinCluster来解说,而不用cluster。(cluster很多人误会是通过勾上Relative选项来达到此目的)
实际上,次级控制器的技术和很多其他的高级的设置技术都是从以下的公式中诞生的)
skinCluster蒙皮计算公式:
V'w:点经过变形后的位置
Vw:变形前的点的位置
Mbpm(k):每个骨骼在蒙皮物体一瞬间的世界逆矩阵
Mdm(k):每个骨骼当前的世界矩阵
W(k):每个骨骼对该点的影响权重值
n=所有的influence(joint)数量-1
骨骼在蒙皮模型时的一瞬间,skinCluster节点会记录下当时骨骼的worldInverseMatrex(世界逆矩阵)数据,而这个数据就记录在skinCluster的bindPreMatrix当中。
那么蒙皮后,骨骼被移动,骨骼的worldMatrix会通过属性连接传递给skinCluster的matrix(我们称其为drivenMatrix)。
线性代数好的朋友通过公式可能已经明白了,我们要做到骨骼父物体移动时而不产生变形,只需要使bindPreMatrix与DrivenMatrix恒互逆即可。这样两者进行矩阵乘法运算得到的结果永远都是单位矩阵。而任何点左乘单位矩阵等于该点本身,所以变形将不会发生。
Vw(点)*I(单位矩阵)=Vw(该点本身)
那么我们要做的是,将骨骼的parentInverseMatrix连接到相对应的skinCluster的bindPreMatrix上即可(或者将骨骼父节点的worldInverseMatrix连接到对应的skinCluster的bindPreMatrix上,两者是相同的)。
估计当年cat_face_final_merge.ma 这个文件很少人注意那些次级控制器(cluster)都被其父节点的worldInverseMatrix所连接,反而去关注rivet技术,如下图:
实际上这个连接才是核心部分。
接下来说详细步骤(对数学过敏的可以跳过原理,直接看步骤):
1,对角色的头部蒙皮并刷权重,并将模型改为face_skin
2,添加表情目标体到蒙皮变形层级前
3,在face_skin模型上给需要次级控制器的部位添加毛囊
4,在毛囊下放置一个骨骼,命名为secondryControl 骨骼的轴向需要和毛囊的轴向完全一致(将骨骼的joint orient 属性全归0即可)
5,在原点创建1个骨骼, 命名为 zeroJoint 为了分担不需要的模型点的权重
6,复制一个模型出来,命名为 face_secondrySkin 用face_skin模型给face_secondrySkin模型添加一个blendShape,并且将blenShape的值调整为1,这样骨骼蒙皮和表情目标体的变形就都能传递到新复制出来的模型上。
7,用secondryControl 和 zeroJoint 给face_secondrySkin蒙皮,并刷好权重。
这时无论是旋转骨骼还是调整face_skin模型下的blendShape值都会使模型有次级控制器的地方发生双倍位移,如下图:
9,按上面理论来说,我们需要查看secondryControl连接到face_secondrySkin模型的skinCluster的matrix[?]上
例如,此例中secondryControl.worldMatrix 连接到了skinCluster2.matrix[0]上,那么这时我们将secondryControl.parentInverseMatrix 连接到 skinCluster2.bindPreMatrix[0]即可,双倍位移得到解决,次级控制器完成.
(这样连接后,只有移动骨骼模型才被变形,而移动骨骼的父节点,不会有任何的变形产生)
当然明白了原理后,以上过程要通过程序写脚本实现是相当容易的。