自己研究的主要是ogre引擎,最近由于在做SBS的蒙皮研究,所以系统的学习了一下骨骼动画的实现源码.由于GEEgine(具体参考《3D游戏引擎设计与实现》)是仿照OGRE的骨骼动画实现的,所以我先以这个为切入点。
首先说明骨骼动画的思想:大致就是在骨骼和mesh之间建立一种关联,这种关联诱使在骨骼运动的时候mesh也做运动,在这里我们暂且不考虑IK.通过系统的研究源码和参考论文。个人感觉很多概念性东西在和具体实现起来时总会有或多或少的‘冲突’,从而总让人感觉有点置身于云里雾里。如果不弄明白之间的联系,很难对蒙皮做出进一步的改正。我这里谈谈自己的心得体会:第一:可以换种思维方式,把骨骼和顶点之间看成是相对的关系;第二,要能够区分全局坐标系和局部坐标系;第三,适当的应用逆向思维.
进入主题:以线性蒙皮为例,在任何文献中你都能看到形似的公式(以D3D为例,OPENGL是右手坐标右乘,类同):V ‘ = V * B的逆矩阵 * A。要看透这个公式,最好自己先去推导一下二维坐标系中一个点用局部坐标顶点和世界坐标顶点两种表示方式的转换。我来讲讲我的理解.由于骨骼动画都是初始空间,就是分配权重的时候骨骼和mesh所在的那个空间,我们要建立骨骼和mesh的关系,要做两步操作:
1,分配权重,有很多种方法,可以自己写程序实现,也可以用Maya帮你完成这一步,具体smooth算法可以参考Jason Weber的《run-time Run-Time Skin Deformation》.
2, 在变换的过程中,顶点根据绑定时候的相对关系,骨骼变换导致顶点也相对变换。
很大部分人纠结的是为什么要求B的逆矩阵,代表意义如何?如前所说,这里需要逆向思维,假设节点V与骨骼arm相关,如下图:
我们要使得在变动arm的时候v也跟着变动,有什么好的方法? 为了简化讨论,我们让骨骼的hip和世界坐标原点重合,如下图:
V * B的逆矩阵的过程其实表明的意思是,把arm的坐标与世界坐标点重合,这是的V点的世界坐标与原来的世界坐标是不一样的,因为原来的世界坐标原点是hip,而现在的世界坐标原点是arm。那这样做有什么好处呢?好处就是,在每一帧做骨骼变化的时候我都可以根据建立骨骼的过程,把V节点也建立好,因为他们之间有的相对关系不变,那么我在建立arm的时候,V也自然而然建立好了。
要理解这个方法,正如前面所言,还要区分好局部坐标和世界坐标,我们要记住一点的是,每一次的操作都是以世界坐标方向为参考系,也即惯性坐标,而不是物体局部坐标,弄清楚了这个,你也差不多明白了LBS了,但是LBS其实是有缺陷的,我争取下节能用公式讲清楚.