2009-10-19
作者: 季卓尔 张景峤
来源: 万方数据
引言
提高计算机动画的画面质量与渲染的效率和减少计算机动画所需占用的空问,已经成为计算机动画使用中比较重要的问题。计算机动画的画面质量与所占用的空间大小成正比,与渲染的效率成反比。越是精致的动画,占用的空间越大,渲染的速度越低。所以如何在保证画面质量的情况下减少动画所要占用的空间,并提高计算机动画的渲染效率成为一个值得研究的课题。较早出现的一种称为顶点动画的三维动画技术,根据时闯对两个关键帧的信息进行插值计算,以得到对应时间的动画数据。其优点是实现起来比较简单,所需的计算量也很少。但它同时也带来一些问题。比如,顶点动画需要占用大量的内存,插值计算时动画容易产生变形等。由于顶点动画的一些问题,一种新的方法被提出,即骨骼动画,它特别适合于人物和其它的脊椎动物的动画模拟。骨骼动画作为一种新的动画技术,它与许多技术进行了结合。比如在骨骼动画中融入了正向反向动力学,电影中常用的动作捕捉技术等“I。WuFu-ehe等嘲提出了一种创建骨骼的方法,称为范围连接图方法。这种方法保留了拓扑结构的信息,并且它不像中间轴变换方法那样对模型摆动比较敏感。尤其应用于复杂模型时得到的结果十分符合人的感觉,使动画显得更加的真实。骨骼动画的诞生对于游戏渲染引擎来说是一项莫大的进步,它在很大程度上提高了游戏中人物渲染的效率。渲染引擎包括了骨骼动画,粒子系统,LOD(1evelofdctial),光照系统,阴影等诸多组成部分。作为渲染引擎的一部分,对于如何提高骨骼动画的运行效率,应从整个系统的高度去考虑。
GPU(graphic process unit)作为游戏渲染的重要硬件之一,随着其处理能力的不断提升,和可编程性能的不断完善,如何让GPU代替CPU完成更多的工作已成为国际计算机图形处理及其相关领域的研究热点之一。吴恩华等人叫介绍了一些在GPU中实现辐射度、光线跟踪、碰撞检测、流体模拟方面的文章,并提出了一些关于使用GPU像素Shader进行代数运算的方法。沈潇“1等提出了一种基于可编程图形硬件的实时的阴影生成算法,改善了阴影渲染效果,并且防止了走样。Yang Xiao嗍等提出了一种基于GPU的实时处理阴影锥的方法,相对于过去在很大程度上提升了阴影生成的效率。Aaron旧等提出了一种基于GPU的数据结构库,使GPU编程者可以根据不同的算法使用不同的数据结构。Cbristophd”等提出了一种基于GPU的实时网格简化方法,将网格简化算法移植到GPU中,并提出了一种通用计算的数据结构,这种数据结构使用于流处理器架构。对于骨骼动画而言,将某些计算移植到GPU中去无疑对骨骼动画,乃至整个渲染引擎的效率而言都有很大的提升。Kipfe一"1等提出了一种基于GPU的实时大规模的粒子系统,并构建了一个通用的粒子系统的引擎,该引擎还实现了粒子之间的碰撞和可见性排序等功能。Shiue等人91提出了一种基于GPU的实时细分方法。他提出的实时GPU细分核心在不同细分深度生成细分网格,使得所有的计算工作都可由GPU的Shader来负责,由此细分算法的所有主要的特征能够得以实现。
1、基础知识
1.1骨骼动画
骨骼蒙皮动画也叫做骨骼动画。使用骨骼动画技术。可以塑造出各种各样,栩栩如生的动画角色。其中,人体的骨骼动画运用得最为广泛。一般来说,骨骼动画由两部分来表示。一部分是形成层次的一系列的骨骼,通常称为骨架,另一部分是蒙在骨架上的皮肤。
骨骼结构是一系列相连接的骨头,它们组成一个层次叫骨层级。其中一个骨头称为根骨,它是整个骨骼结构的关键,整个骨架都是由它发展而来。其它的骨头都附属于根骨,要么是它的子骨要么是它的兄弟骨。由此组成如图1所示的骨骼结构。在检索骨架的时候,一般先找到形成骨架的根骨,然后,由根骨开始进行检索,直到找到所需要的骨骼。
在骨骼动画中仅仅建立骨架是不够的。为了使骨骼可以动起来,一般通过对骨骼进行变换达到使模型动起来的效果。在对骨骼做完变换之后还需要更新整个骨架,以此来产生一个新的动作。骨骼的更新需要遵守一些规则。图2展示了骨骼更新所需要遵守的规则。
在图2中,整个骨骼的更新从根骨开始,直至所有的骨骼都更新完毕。每一个骨骼的变换都会影响到其兄弟骨骼和子骨骼。这种影响在一定的范围内会一直传递下去。
骨骼和骨架只是个概念结构,用于控制模型的动作,它与模型网格相关联。通过骨骼来控制网格,从而让模型动起来。这里的模型网格就是所谓的蒙皮网格。
在蒙皮网格中,所有网格点均与骨骼相关联。因此,只要对骨骼进行变换,再对与骨骼相关联的网格点做相应变换后,就可以使模型动起来。
在骨骼动画中每个顶点都与骨骼相关联,骨骼的运动会带动附于其上的顶点。骨骼对顶点的影响力的大小由每个骨骼的权重系数决定,对某个顶点产生影响的骨骼的权重总和为l。
使用骨骼动画可以节省许多内存空间,且能够较好的控制模型网格的变换。但是,骨骼动画的这些好处也是要付出一些代价的,与较少的内存消耗对应的是更大的计算量。由于现代CPU的超强运算能力以及GPU通用计算的发展,这似乎不是一个大问题。甚至可以把一部分计算转移到GPU上去,以节省更多的CPU计算能力给其它的部分的计算。
1.2可编程Shader技术
在过去GPU中的Shader分为两类,即顶点Shader(Vertex Shader)和像素Shader(PixelShader)。这两类Shader分别位于渲染管线的不同阶段,分别处理顶点和像素的数据。两类Shader只能各自处理各自的数据,即便Shader空闲也不能用于另一方数据的处理。
当今最先进的GPU已经不再区分顶点Shader和像素Shader。nVidia将二者合并由流处理器来代替,形成了统一渲染架构,使得所有的处理都在流处理器中统一进行。这样在GPU中处理数据的时候所有的处理单元都会被使用到,不会出现Shader空闲的问题,极大的提升GPU的处理效率。本文的算法正是基于此种架构设计的。在统一渲染架构中,顶点Shader和像素Shader拥有了相同的处理能力。所以过去许多因为像素Shader处理能力强而在像素处理阶段实现的算法,
可以根据需要转移到顶点处理阶段来进行。虽然在统一渲染架构中合并了两类Shader,但是渲染管线中的顶点处理阶段和像素处理阶段仍然存在。除了原先的顶点和像素处理阶段,在新的GPU架构中还增加了几何Shader(GeometryShader)。新的处理管线如图3所示。
2、基于可编程GPU的骨骼动画
在骨骼动画中涉及到大量有关于顶点的计算,如果将所有的这些计算都放在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中的纹理进行采样能够得到骨骼矩阵,最后利用骨骼矩阵对顶点信息进行更新。
3、实验结果
实验1是在P43.0的计算机上进行测试的,使用的显卡是ATI R300,内存512M。表1描述的是骨骼动画的程序不使用可编程GPU与使用可编程GPU时每秒所绘制帧数的对比。
由表1可以看到,使用了GPU之后,绘制的效率相对于不使用GPU有了很大的提升。而且在某一个范围之内,绘制的人物数量越是多,得到的性能提升越是大。所以当计算量越大时,CPU越会成为提升计算效率的瓶颈,使用Shade越能够使性能得到提升。但是这种提升也不是无限制的,从上表的统计结果可以发现,当绘制的任务数超过某个量的时候,效率就不再提高了。这是因为此时GPU的性能已被用尽,效率的提升已达到极限。如果想要再提高效率,则只有使用更高性能的显卡。
以上分析表明,使用GPU可以大大提高计算机系统计算的整体效率,并且这种提升在不超过一定极限的情况下,会随着计算量的变大而变大。
实验2的硬件环境是Intel PentiumD925处理器,King StoneDDRII 6672G内存,nVidia8800GTS显卡。使用的软件环境是WindowsVISTA。使用的开发环境是MicrosoftVisualStudi02005,DirectX 10,DircctX SDK April 2007。使用的模型源自微软,有4000多个顶点与6 000多个三角面片。表2为在CPU利用率较低的情况下,各种基于GPU骨骼动画的运行效率,并以静止网格(即只是显示静态模型,但并不对其进行骨骼变换)的渲染为参照。表3为在CPU利用率较高的情况下,各种基于GPU骨骼动画的运行效率,并以静止网格的渲染为参照。
表2的数据可以分为3个阶段来分析:①在渲染的模型数量较少时,由于GPU的运算能力比较强,所以GPU更新骨骼和预创建骨骼动画的方法相对于CPU更新骨骼的方法而言效率高一些。②当渲染模型的数量增加了一部分后,由于闲置的CPU帮助CPU更新骨骼方法分担GPU的一部分计算量,充分利用了CPU与GPU的资源,使得CPU更新骨骼方法获得了更高的效率。③当渲染模型的数量急剧增加后,由于CPU与GPU的负担均加重,闲置CPU分担GPU计算量的能力下降,GPU的计算能力也被大大消耗,所以出现了CPU更新骨骼方法与预创建骨骼动画方法效率相等的情况。
从表3的数据中可以发现,当CPU高负载运行时.GPU更新骨骼和预创建骨骼动画方法的效果要比使用CPU更新骨骼动画的方法要好。
综合以r.的数据可以发现,使用了GPU之后骨骼动画的效率有显著提高的。但骨骼动画效率的高低还取决于它所处的环境。只有最大限度的利用整个系统的资源才能得到最高的效率。
4、结束语
本文主要讨论了几种基于可编程GPU技术的骨骼动画口通过使用不同的可编程GPU技术,将骨骼动画不同部分的计算任务放到GPU中进行,使部分或者全部的计算量从CPU转移到GPU,从而将CPU从繁重的顶点变换,甚至骨骼更新的计算中解脱出来。本文在肯定了基于GPU的骨骼动画效率提升的同时,对不同的骨骼动画方法进行了分析,并指出骨骼动画效率的提升取决于其所处的环境。骨骼动画的价值体现在其所处的系统,比如游戏引擎。作为游戏引擎的一部分,骨骼动画方法的选择应该从引擎效率最大化的角度去考虑。单独考虑提升骨骼动画效率的意义并不是很大。
随着GPU的不断发展,越来越多与图形相关的算法可以移植到GPU中去。不仅骨骼动画,同样。光照系统,粒子系统,LOD*阴影,模型简化都可以从GPU中受益良多。事实上很多与图形相关的算法都用到了GPU技术,不过在渲染管线不断改进与完善的今天,更多基于GPU的算法可以被提出。