在骨骼动画中涉及到大量有关于顶点的计算,如果将所有的这些计算都放在CPU中进行,那么CPU与GPU将处于一种利用率不平衡的状态。当系统总负载越来越大时,CPU就成为提高系统效率的瓶颈,减轻CPU的负担成为一种必然的选择。由此,可以将一部分与顶点相关的计算放入到可编程的GPU中进行。下面将给出本文所设计的3种在GPU中实现骨骼动画的方法。
2.1骨骼动画中主要数据计算的分析
由于CPU与GPU构造的不同,决定了他们计算与数据存储方式的不同。所以,基于CPU的算法并不能够简单的复制用于GPU中,必须先要对其进行分析与简化。骨骼动画中的数据计算主要包括以下4方面,骨骼与顶点的对应关系,骨骼的偏移矩阵与骨架的对应关系,骨架的更新,顶点的更新。
使用GPU迸行计算与使用CPU进行计算有很大的不同。GPU在顶点处理阶段处理的每一个点,都使用同样的算法进行计算,对于像素处理阶段的每一个像素也是如此。并且在GPU中每个顶点或者像素的计算是相互独立的。当前的计算结果不能用于下~个顶点或者像素。而且顶点与顶点之间,像素与像素之间,计算结果不能被共享。由此可见,GPU较适合处理逻辑比较简单的任务。所以在设计基于GPU的算法时应尽量保证程序的简洁。
在了解了GPU的计算特性之后,下面将对这4种计算分别进行分析:
·骨骼与顶点的对应关系:骨骼与顶点的创建是分开的,但在创建的过程中,我们要将骨骼与顶点绑定在一起。这样当我们改变骨骼时,顶点才会跟着一起移动。
·骨骼的偏移矩阵与骨架的对应关系:骨骼的偏移矩阵规定了绑定在某个骨骼中顶点的偏移量,它与骨架一起控制了顶点在空问中的位置。
·骨架的更新:骨骼矩阵的改变会对它的兄弟骨骼和子骨骼产生影响,所以要对相应的骨骼进行更新,即骨架的更新。
·顶点的更新:在整个骨架的位置改变后,附着在骨架七的顶点当然也需要改变,这样才能使模型动起来。被改变的顶点信息有顶点的位置及顶点的法向量。
从以上分析可以发现:骨骼与项点的对应关系需要保留计算结果以用于下一步的计算,并且由于涉及到很多的查找计算,所以算法相对比较复杂。骨骼的偏移矩阵与骨架的对应关系同样需要保留计算结果用于下一步的计算,同样因为涉及到很多的查找计算,所以算法也相对比较复杂。骨架更新的计算结果也需要保留并且由于骨架采样是树形存储结构,一股使用递归的方法进行更新。算法比较复杂,也并不适合在GPU中计算。但是,因为骨骼动画是许多不同骨架的演化结果.所以仍有办法在GPU中生成新的骨架。顶点更新的结果可以直接输出到屏幕上而无需保留,所以顶点更新是骨骼动画中最适合GPU计算的一部分。
2.2 CPU与GPU之间的数据传递
在过去的骨骼动画中,所有的计算都在CPU中进行,计算得到的所有结果都放到顶点缓存中,然后送入GPU,最后绘制在屏幕}二。由于本文的方法将顶点更新甚至骨架更新的一部分计算放到GPU中去处理,因此不仅要将原始的顶点数据送入GPU中,而且还要将所有用于顶点更新的数据信息一同传给GPU。
由于CPU与GPU之间进行数据传递并不像CPU从内存中调用数据那样方便,二者之间的数据传递相对来说是比较费时的,特别是在传递大段数据的时候更是如此。所以在算法设计中应尽量减少两者之间数据传递的频率,并且传递的数据量不要太大。CPU与GPU之阆数据的传递方法有两种:①直接传递,该方法在传递数据时消耗比较大。传递后的数据放在GPU的内存中,在GPU计算过程中调用比较方便;②利用数据纹理进行传递,该方法在数据传递时消耗比较小。但传递后的数据存放在GPU的纹理内存中,为了获取所需的数据,我们需要计算出数据在纹理中的位置,并对相应位置的纹理进行采样。
2.3几种基于可编程GPU的计算方法
2.3.1 CPU更新骨骼,GPU更新顶点信息
本方法将逻辑较为复杂的骨架更新等工作放在CPU中进行计算,将逻辑较为简单的顶点更新放在GPU中进行计算,充分利用了CPU与GPU的资源。但是由于骨骼更新的工作在CPU中进行,所以在每次渲染的时候都需要将更新后的矩阵传入GPU中去。如图4所示,首先在CPU中对骨骼与顶点的对应关系,骨骼的偏移矩阵与骨架的对应关系进行了计算,对骨骼矩阵进行了计算更新。然后将更新后的矩阵和顶点信息传入GPU中。最后在GPU中利用传入的骨骼矩阵对顶点信息进行更新。
2.3.2 GPU更新骨骼与顶点信息
本方法是顶点动画与骨骼动画的结合,用一组起始位置的骨骼矩阵和一组结束位置的骨骼矩阵来表示一段动画,即对始末位置骨骼矩阵进行线性插值得到中间动画姿势。本方法在初始化的时候完成起始位置骨骼矩阵和结束位置骨骼矩阵的计算工作,然后将所有与骨骼动画相关的计算都放入GPU中完成。本方法的优点在于减少了CPU与GPU之间的通讯,缺点在于仅使用GPU进行计算,浪费了CPU的资源,加重了GPU的负担。如图5所示,首先在设备创建的过程中对骨骼与顶点的对应关系,骨骼的偏移矩阵与骨架的对应关系,起始骨骼矩阵和结束骨骼矩阵进行了计算。然后将计算好的矩阵传入GPU中去。最后在GPU中对起始骨骼矩阵和结束骨骼矩阵进行插值运算,得到当前时间点的骨骼矩阵并利用该矩阵对顶点信息进行更新。
2.3.3预创建骨骼动画方法
本方法以数据纹理作为传输方法,通过将骨骼动画创建到纹理中,再通过纹理采样的方式来获取骨骼矩阵。本方法的优点在于减少了CPU与GPU之间的通讯,缺点在于仅使用GPU进行计算,浪费了CPU的资源,加重了GPU的负担。但是数据纹理作为一种能方便传输大量数据的方法,为实现骨骼动画提供了另一种途径。
预创建骨骼动画法可以将骨骼动画数据制作成纹理,也可以创建一个纹理的ResourceView将数据映射到纹理中去。前者需要事先创建好纹理,而后者需要在初始化的过程中,计算骨骼动画的信息并映射到纹理的ResourceView中。如图6所示,首先需要创建一个纹理或者一个ResourceView,然后将该资源传到GPU中去,然后对传递到GPU中的纹理进行采样能够得到骨骼矩阵,最后利用骨骼矩阵对顶点信息进行更新。