说明12数媒班级_第1页
说明12数媒班级_第2页
说明12数媒班级_第3页
说明12数媒班级_第4页
说明12数媒班级_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、(设计)(设计)题目:基于 GPU的布料运动仿真系统名姓学号201200302004院 山东大学软件学院 学业数字专年级2012 级指导教师2016 年 6 月 5 日目录摘要.3第 1 章 绪论.61.1背景.61.2现状.71.3的主要工作 .91.4整个的结构.9第 2 章 布料系统中的数学模型.112.1质点弹簧模型.112.2时间积分.152.2.1verlet 时间积分方法 .162.2.2显式计算方法.172.2.3隐式计算方法.172.3碰撞检测和处理.182.3.1碰撞检测.182.3.2碰撞处理.192.4GPU.202.4.1GPU中的分块策略 .222.4.1GPU中线

2、程的同步 .23第 3 章 系统具体的实现和架构.263.1 系统的具体实现步骤.263.2 系统实现的架构.273.2.1布料建模.273.2.2纹理和灯光材质的设置.303.2.2关于场景中碰撞球体和地板的建模绘制.323.2.3关于场景中碰撞球体的碰撞检测.333.2.4布料仿真系统中的交互设计.343.2.5 风力的计算.393.2.6 GPU的过程 .41第 4 章 实验结果.474.1系统开发的硬件软件环境.474.2不同时间积分方式的比较.474.3在相同情况下 CPU 和 GPU 的渲染对比.48第 5 章 结论.495.1 总结.495.2 未来展望.49致谢.51参考文献.

3、52英文文献.53中文译文.56基于GPU的布料仿真系统摘要计算机仿真技术是计算机动画的热门方向,其中布料仿真技术也在大规模普及。现如今柔性曲面仿真技术已经在许多应用场景进行了商业化的尝试,但是仍旧没有进入大规模使用。在计算机动画、虚拟服装展示以及仿真试衣间,或者高级造型设计师的模拟设计,布料仿真都扮演着角色。基于物理模型布料的模型建立主流有质点弹簧模型,有限元模型和弹性变形模型。大部分基于物理模型布料仿真系统是在建立模型的条件下,进行了时间积分,通过动力学的运动规律来布料的运动。因此基于物理的模型布料更注重物理性质上的真实性,同时在整个运动过程上符合运动规律。由于计算机仿真对计算速度的要求比

4、较高,都在算法和硬件条件上尝试对仿真进行。由于算法加速的性能有限,今年来大部分的突破都是在硬件条件的改进。其中GPU因为计算模块多,同时布料的并行计算并行度高,计算多而简单,适合使用GPU来进行。所以使GPU在布料仿真系统中脱颖而出。本文描述了基于物理模型来仿真布料,在时间和空间上对布料仿真问题进行离散化。把整块布料视为质点和弹簧组成的可变形曲面网格,然后基于动力学的原理计算质点和弹簧的受力。使用verlet时间积分的方式来迭代,模拟网格的运动。同时,在计算的基础上使用NVIDIA的CUDA进行了GPU的,使仿真的计算时间大大缩短。在这个场景中,也进行了简单的碰撞检测和交互设计,让场景更加丰满

5、。关键字:布料仿真;弹簧质点模型;GPUABSTRACTComputer simulation technology is the hot research direction of computeranimation, the cloth simulation technology is also being widely used. Nowcommerl attempts of flexible surfaimulation technologye been tried inmany application scenarios, but still do nove acs to large

6、-scale use. Incomputer animation, games, virtual clothing display, simulation fitting, or seniordesigners ofog design, cloth simulation plays the core role.Based on the physical m, the maof the mass-spring isestablished, the finite element mand the elastic deformation mas well.Most of the simulation

7、 system based on physical mishe condition ofestablishing the m, and the timeegration is carried out. Therefore, thephysical mof cloth is more emphasis on the physical properties of theauthenticity, whilehe whole pros of movement in line with the laws ofmotion. Because of the high requirements of com

8、puter simulation, the researchers try to speed up the simulation on Algorithms and hardware conditions. Due to the limited performance of the algorithm, most of the research breakthroughs are improved in hardware conditions. GPU because of the calculation module, theparallel calculation of cloth par

9、allel computing is high, and the calculation is moreand more simple, suitable for use GPU to speed up. So Gsimulation system to stand out.ccelerated in clothhis pr, a physical mbased is described, which is based on thediscretizationsime and space. We regard the whole fabric as a deformablesurface me

10、sh consisting of masses and springs, and then calculate the force ofmasses and springs based on the rules of dynamics. The timeegration method isused to iteratively simulate the grid motion. At the same time, on the basis ofcalculation, we use CUDA NVIDIA to accelerate the procedure, sot thecompuion

11、 time of the simulation is grey shortened.his scene, also carriedout a simple collifullness.detection anderactive design, sot the scene moreKey words: Cloth Simulation; Mass-spring M; Gccelration第1章 绪论1.1背景自20世纪末,计算机技术不断进步,CPU、GPU计算能力不断更新换代,软件工程理念不断变化。计算机图形学日益通过动画等各个方式进入每个人的生活。而布料仿真技术,作为计算机图形学的重要部分,

12、同样一直是布料仿真技术在不同的领域中也有着广泛的使用:的热点1。在计算机动画和领域,通过计算动力学来模拟布料的运动,大大降低了动作绑定的工作量替代了原来枯燥的设定布料运动轨迹的工作。同样,对布料进行实时计算,使布料更加呈现柔顺丝滑的效果,相比于原来仅仅通过贴图来模拟布料的褶皱更容易让观众或者玩家有出色的沉浸感和视觉体验。在洗衣机、衣物的和影视制作中,布料仿真技术往往扮演着节约成本、增加视觉冲击感的重要角色。在CAD/CAM领域中2,服装设计师可以通过布料仿真技术,在计算机上模拟出服装成品,省略了将成品制作的过程,减少了整个工作流程中时间和成本上的损失。同时,布料仿真可以在短时间模拟出不同体型,

13、不同、甚至是不同物种的身材(包括机器人、拟人角色),避免了成衣过程中大量重复劳动。在衣物材质上,布料系统也可以模拟各种尺寸、图案、衣物的光滑程度、弹性系数,原来改变需要大量成本的,都成为布料仿真系统中可以调节的参数。布料仿真技术是通过数学模型来模拟布料系统是物理属性,布料本身就是一个复杂的应力-应变系统,同时还有各种摩擦力布料本身的弹力重力和质量等属性来逼近布料的运动状态。尽管如此,布料随着近些年的理论完善,已经出现了许多仿真效果非常优秀的模型,为整个布料仿真的提供了夯实的理论基础。今年来,布料仿真的技术不断发展,人们构建了许多模型来拟真布料的各种性质,在仿真的渲染时间、稳定性和效果方面做出了

14、很大,但是仍然没有达到工业广泛使用的条件,期待今后布料仿真技术可以通过技术和硬件设施的进步,能够被大部分玩家和普通用户能够使用。1.2现状自从1986年,首个布料仿真模拟系统的出现,通过许多模型来仿真布料的运动状态的性质,布料同时具有刚性物体和柔性物体的性质,因此就让建立模型较为复杂,建立布料的模型、计算运动的时间积分方式、碰撞检测和碰撞处理是影响拟真视觉结果的三个重要。目前计算机图形的布料仿真可以分为三种方法:几何方法、物理方法3和混合方法4。几何方法是不考虑布料的物理性质,直接模仿布料在状态下的视觉特征,例如布料在悬挂状态下的悬链形状来模拟褶皱的轨迹。物理方法是通过获得布料的动力学特征构建

15、模型,通过计算每一个时刻布料的位置、速度、度等状态来判断布料的运动轨迹和最终状态。而混合方法采用了两者共同的特征来达到模拟的效果。常用的物理模型包括质点弹簧模型5、弹性变形模型6、有限元模型7。本文主要采用了质量弹簧模型,在精确性和渲染实时性之前进行折中。将布料离散为三角形网格,将布料的质量分散为这些质点的质量,同时只考虑质点的运动状态,通过质点之间的弹簧模型来模拟布料的拉伸、弯曲、错切的情况,然后通过质点的连接来体现整个布料的空间连续运动状态。由于布料的受力和布料的拉伸、错切、弯曲并不是简单的线性关系,如果仅仅用线性弹簧模型来拟真就会出现大量的误差。Provot8采用经典的质量弹簧模型的同时

16、,直接修改了非线性弹簧的拉伸率,解决了超弹性问题,但是这样的显示方法计算仅仅适用于计算规模比较小的网格体系。虽然模型不够精确,但是可以在简单计算的过程中保证高效率,从而达到实时效果。这种方法的缺点是不够稳定,只能选择小步长,对大规模的布料仿真系统就为力。数值积分方法对布料系统仿真有很大的影响。质点弹簧系统都是将一个个质点当前的位置、速度、度来求出下一个时刻的位置、速度、度。因此通常得到一个偏微分方程组,解方程组的过程就出现了不同精度和稳定性的方法。这些方法大致可以分为:隐式积分、显式积分和半隐式积分。隐式积分具有较强的稳定性,但是在计算的时候需要反复迭代来求出方程解,计算开销大,可以使用较大的

17、时间步长。相对比,显示积分稳定性不足,计算简单,速度快,但是在视觉效果上往往显得比较生硬,常常出现布料物理上的错误。本文将采用verlet时间积分的方法,并且将verlet和显式比,观察这些方法的稳定性和渲染速度。、隐式进行对布料仿真系统同样要对布料的碰撞问题进行处理。首先要检测布料之间是否有碰撞,其次检测布料和设定的物体之间时候会发生碰撞。在检测到碰撞之后将会对碰撞进行处理,碰撞的处理也分为不处理,直接将碰撞后的质点的速度设为0,或者进行简单处理:将质点之间的速度进行方向上的翻转和大小上的衰减。如果仅仅使用单核CPU进行渲染,当下可靠的计算方法就需要消耗十几秒来计算一帧的只包含一万个三角形网

18、格图形结果,现在的流行趋势集中在绘制更复杂的角色服装的拟真结果。角色服装的潜在几何复杂性在网格数量上远远超过一万个三角形网格。而且,多层衣物之间几乎紧贴在一起,意味着在段时间物就可能发生大量的碰撞,这就要求用更复杂的时间积分方式来保证稳定性,以免发生衣物之间相互穿插的现象。对于高质量的动画,每层衣物可能会包含十万数量级的网格。这里还需要强调,一个被忽略的碰撞检测可能同样会让整个渲染过程产生错误的结果并且可能会非常明显地出现在渲染结果中。为了抑制布料之间相互穿插,许多拟真系统采取了连续的碰撞检测(CCD)9。以上都对计算提出了比较高的要求。以此,开始接触多核CPU和GPU来运算。主要的人有:in

19、daraju等人10,Selle等人11,Pabst等人12,Lauterbach等人13,人14。等随着可编程GPU的到来,便充分利用并行计算来对布料仿真和碰撞处理进行。在2004年,Green15开始使用GPU和verlet时间积分来展示快速布料仿真技术,但是只能处理和球体的碰撞检测,没有考虑到自碰撞。Zellar16在原来的基础上展示了简单的基于GPU的算法,并且对碰撞检测和风力的动作做出了响应。在2009年,ATI使用了OpenCL API展示了基于GPU的布料仿真17。许多基于GPU包括时间积分和碰撞处理的高效算法不断被提出和改进,并建立可变形的模型。目前,提出流式模型来精确的碰撞检

20、测。1.3的主要工作首先实现布料仿真的质量弹簧模型,通过建立三维网格来构建布料网络。考虑布料内部的受力、重力、阻尼力的作用,将时间步长设置为h,然后根据每个时刻每个质点的受力,计算出下一个时刻的受力,可以得出一个常微分方程组,然后使用verlet算法求出下一个时刻每个质点的动力学情况,从而模拟布料的运动。然后进行碰撞的检测和碰撞的处理,做出更好的视觉连贯效果。另外,在布料系统的基础上,添加常见的固体在场景中,增加场景的真实效果。同时,加上了一些交互方式。使用者可以通过拖动来改变点的位置。1.4 整个的结构这篇将以以下行文结构来展开:第2章主要描述整个系统使用的数学模型,包括布料模型、时间积分方

21、式和碰撞检测等等方式。第3章主要描述系统的具体实现细节,这章会详细地从代码角度来谈谈系统的一些具体的细节方面。第4章主要描述系统实现的结果,以及不同的纵向横比。第5章就是的结束语和一些不足之处。第2章 布料系统中的数学模型2.1 质点弹簧模型本文使用的弹簧-质点模型是由Provot提出,经过后人的不断完善得出的模型。质点弹簧模型是将布料视为一个质点和弹簧的系统,质点代表了布料的位置和质量,它将布料在空间上和质量上的连续进行简化和离散化,而弹簧代表了布料的内部受力。事实上,布料是由一根根的,在布料的一个维度上大致有数以千计的受力简化成质点之间弹簧的受力。而且不同,也将衣物形变过程中的的布料织发受

22、力方向、弹性系数都大相庭径。因此仅仅仿真其中三种比较重要的影响布料变形的受力,即45度和90度方向的受力和布料弯曲的受力,而且假设横向纤维和纵向的物理机械性质相同。为了模拟布料内部不同方向上的相互作用,对三种不同的弹簧设置不同的弹性系数和阻尼系数。在整个过程,计算没一个点受到的每一根与这个质点相连接的弹簧对于这个质点的作用力。为了便于实现,假设有一张质量均匀的布料,而且布料是厚度为0的理想空间曲面。对于一根弹簧,会有四种不同的作用力,弹簧的弯曲、弹簧的压缩、弹簧的错切和弹簧的扭转。那么对于一块分布的布料,其内部的应该也可以归结为受到三种力(不包括弹簧的扭转)。同样的,布料内部力归纳为三种相互作

23、用力:拉压、剪切和弯曲,可以分别使用结构弹簧、剪切弹簧和弯曲弹簧来模拟。但是在这个过程,对于结构弹簧和错切弹簧,只考虑弹簧的压缩,不考虑弹簧的弯曲和错切。对于弯曲弹簧,只考虑弹簧的弯曲,而不考虑弹簧的压缩和剪切。如图为弹簧-质点模型的示意图以及三种弹簧。弹簧的弹性系数主要取决于整块布料的材料和物理特性。如图2-1所示,即为质点的分布和质点周围的三种弹簧分布情况。1、结构弹簧布料主要的抵抗拉伸的作用力由结构弹簧来模拟,而且布料对于拉伸作用力的抑制最大,因此结构弹簧的弹性系数是三种弹簧中最大的。它连接的是向相邻的,即质点P(i, j)和质点P(i-1, j)、P(i+1, j)、P(i, j-1)

24、、P(i, j+1)。两个方图2-1 质点弹簧模型中质点和弹簧的分布2、弯曲弹簧布料抵抗弯曲的作用力由弯曲弹簧的拉伸力来模拟。布料对于弯曲作用力的抑制最小,因此弯曲弹簧的弹性系数是三种弹簧中最小的。它连接的是方向上间隔一个质点的两个质点,即质点P(i, j)和质点P(i+2, j)、P(i, j+2)、P(i-2, j)和P(i, j-2)。 3、错切弹簧布料抵抗倾斜方向拉伸的作用力由错切弹簧的拉伸力来模拟。布料对于弯曲作用的抑制介于弯曲和方向的拉伸之间,因此错切弹簧的弹簧系数介于两种弹簧之间。它连接的是45度倾斜方向的两个质点,即质点P(i, j)和质点P(i+2, j+2)、P(i-2,

25、j+2)、P(i-2, j-2)和P(i+2, j-2)。弹簧质点模型的力学分析如果需要了解布料的运动状态,积大,不能将整块布料视为一个质点,所以须对布料进行受力分析,因为布料表面须考虑到布料的内部受力。由于真实布料受力情况复杂,所以对受力进行简单化的处理即通过质点弹簧模型中质点的受力分析,综合得出整块布料的运动状态。对布料上的质点进行受力分析,大致可分为内力和外力。内力是指质点之间的相互作用力用来内力模拟布料的弹性,其中主要有错切力、弯曲力、拉伸力和阻尼力。其簧的错切力、弯曲力和拉伸力只和弹簧的位置有关,而弹簧阻尼力是由质点的位置和质点的速度同时决定的。弹簧阻尼力正比于质点的速度。外要是布料

26、在虚拟环境下受到的作用力,其中包括受到空气阻力、重力和外界拉力的作用。重力恒定不变,空气阻力正比于质点的运动速度。第二定律决定了布料上的质点运动规律,它描述了质点所受到的合力、质点的质量和质点这个时刻的度的关系。知道质点的受力后,质点所有的力矢量相加,得出质点最终的受力情况F,然后根据质点的质量m,就使用第二定律F=ma,来计算质点的布料的运动状态:度a,从而计算出质点的速度和位移,最后得出整个来计算弹簧的弹力。定律是描述弹簧的压缩或拉伸量、弹簧系数以及受到的弹黄弹力之间的关系。作用在质点布料的风力角形的面积以三角形面片为基本处理,首先通过公式计算三(式2-5)其中方程求解方法,可以近似得到无

27、限接近原方程的运动过程。这个运动过程就是通过时间积分来进行运算的。在计算时间积分的过程中,就要综合考虑计算规模、仿真特点和要求,选择合适的时间步长和积分方法,避免在计算中不断累计误差,造成不稳定的计算结果和渲染效果。接下来就将简单介绍常见的时间积分的计算方法。2.2.1 verlet时间积分方法Verlet算法是经典力学(力学)中非常经典的一种积分方法,是对第二定律(运动方程)在计算机上运用的一种数值积分方法,在力学计算运用十分普遍,比如分子运动/模拟(Molecular Dynamics/Simulation),行星运动,等等。Verlet算法要解决的问题是,给定粒子等式中未曾出现速度,虽然

28、是或者计算粒子的轨迹,但是很多时候我们需要得知粒子的速度,用来计算粒子的动量。如何计算粒子的速度?可以使用最简单的中值()定理:2、和地板的碰撞:在布料运动过程中,对布料上质点的y坐标进行判断,如果坐标值小于0,则判定质点和地板发生碰撞。通过这样简单的碰撞检测,也可以得到简单的碰撞处理效果,但是这种碰撞检测的方法局限性也非常明显:稳定性不足,常常是已经发生碰撞而没有检测到;而且只能处理边缘简单的物体,如果面对复杂的模型,那就不能适用;并且这种碰撞检测并没有将自碰撞包括在内,当布料之间有接触的时候,就会发生穿插现象;这种碰撞检测的方法计算量也比较大,没有使用数据结构来简化碰撞检测,也没有通过过滤

29、来减少计算量。2.3.2 碰撞处理当质点与平面发生碰撞时,质点会由于产生碰撞而发生响应,即质点的受力状况和运动速度都将发生变化。下面将分别就质点受力改变和速度进行1、质点受力改变当质点受到合力F随即发生碰撞的时候,。2.4 GPUGPU计算是指同时采用图形处理单元(GPU)和CPU,以加快科学、分析、设计、消费者和企业应用程序的速度。GPU于2007年由NVIDIA率先推出,现已在世界各地为支持。GPU能够为从汽车、快速度。、大学、公司以及中小型企业的高能效数据中心提供和平板电脑到无人机和机器人等的应用程序加布料仿真的GPU是使用cuda语言。CUDA是NVIDIA的GPGPU模型,它使用C

30、语言为基础,可以直接以大多数人熟悉的C语言,写出在显示上执行的程序,而不需要去学习特定的显示的指令或是特殊的结构。在CUDA的架构下,一个程序分为两个部份:host端和device端。Host端是指在 CPU上执行的部份,而device端则是在显示上执行的部份。Device 端的程序又称为 kernel。通常host端程序会将数据准备好后,到显卡的内存中,再由显示回。执行device端程序,完成后再由host端程序将结果从显卡的内存中取在CUDA架构下,显示执行时的最小是线程。数个线程可以组成一个线程块。一个线程块中的线程能存取同一块共享的内存,而且可以快速进行同步的动作。每一个线程块所能包含

31、的线程数目是有限的。不过,执行相同程序的线程块,可以组成grid。不同线程块中的线程无法存取同一个共享的内存,因此无法直接互通或进行同步。因此,不同线程块中的线程能合作的程度是比较低的。不过,利用这个模式,可以让程序不用担心显示一个具有很少量执行单元的显示实际上能同时执行的线程数目限制。例如,可能会把各个线程块中的线程顺序执行,而非同时执行。不同的grid则可以执行不同的程序(即kernel)。对一个程序进行GPU,需要有一个先决条件:进行计算的这些部分相互独立,不在数值上相互依赖,那么就可以将需要并行的部分置于不同的GPU线程中进行同时计算。1、分配GPU的数据数据进行GPU空间,主要分为以

32、下几个步骤:在CPU编程中,通常需要做的第一件事是数组大小,决定它用多少字节。同样在GPU中,需要为数据分配内存空间。CUDA使用用带两个参数的cudaMalloc,指针和分配的字节数。cudaMalloc意思是分配GPU上的数据,而普通的Malloc意思是分配CPU上的数据。2、将CPU上的数据移到GPU上接下来做的是从CPU数组数据到GPU的数组,这个调用是cudaMemcpy,它就像普通的Memcpy,但它有四个参数,而不是3个。前3个参数与普通C Memcpy一样,目标地址、源地址和字节。第4个参数是转移方向。转移方向3个选项是CUDA内存主机到设备、CUDA内存设备到主机以及CUDA

33、内存设备到设备。3、在GPU上进行计算CUDA使用kernel函数在GPU上启动内核,启动语句类似于:即内核函数名,然后用三个对应的尖括号包括线程块和线程数两个参数,表示总共在GPU上分别启动多少个线程块,每个线程块分别有多少个线程。然后启动的内核函数后面就是每个线程需要的参数。对于线程内核本身,每个线程都会有一个独特的属性,用来区分每个线程:threadIDX.x和blockIDX.x,从直观上就可以知道分别是这个线程的块序号和每个线程块中的线程序号。CUDA使用这些序号来索引,并进行数据的计算。4、将GPU上的数据重新移回到CPU上verlet(_vbo, X_in, X_last_in,

34、 X_out, X_last_out, texsize, step, damp, mass, dt, inv_cloth_size);在这里,CUDA同样使用cudaMemcpy函数,只不过数据的转移方向变成由CUDA内存设备到主机设备。5、清除cuda缓存,内存最后,CUDA使用cudaFree函数来空,从C语言的角度对所申请的数组所申请的内存,然后内存。需要将数组置以上过程在这个布料仿真系统中主要移动的数据为:各质点在迭代前和迭代后的位置。2.4.1 GPU中的分块策略实际上在nVidia的GPU里,最基本的处理单元是所谓的SP(Streamingsor),而一颗nVidia的GPU 里,

35、会有非常多的 SP 可以同时做计算;而数个ProSP会在附加一些其他单元,一起组成一个SM(Streaming Multiprosor)。几个SM则会在组成所谓的TPC(Texture Prosing Clusters)。对应到cuda来说,应该是没有TPC的那一层架构,而是只要根据GPU的SM、SP的数量和资源来调整就可以了。CUDA的device实际在执行的时候,会以Block为,把一个个的 block分配给SM进行运算;而block中的thread,又会以warp为,把thread 来做分组计算。目前CUDA的warp大小都是32,也就是32个 thread会被群组成一个warp 来一起

36、执行;同一个warp里的thread,会以不同的数据,执行同样的指令。GPU线程以网格(grid)的方式组织,而每个网格中又包含若干个线程块,在G80/GT200系列中,每一个线程块最多可包含512个线程,Fermi架构中每个线程块支持高达1536个线程。为了使程序支持大部分的GPU,的线程数量设置为256。一个线程块内最大因此在程序中,程数量少于256个时,个线程。总共需要运行的线程数量和质点的数量相同,然后如果线就仅仅启动和质点数量相同的线程,反之,则启动256在这个过程中取n=256。2.4.1 GPU中线程的同步在一般程序的整个运行过程中,只有一个控制权的存在。当函数被调用的时候,该函

37、数获得控制权,成为激活(active)函数,然后运行该函数中的指令。与此同时,其它的函数处于离场状态,并不运行。多线程就是允许一个进程内存在多个控制权,以便让多个函数同时处于激活状态,从而让多个函数的操作同时运行。即使是单CPU的计算机,也可以通过不停地在不同线程的指令间切换,从而造成多线时运行的效果。而在进行GPU的时候,就是对多个线时进行控制权,这些线程在相互不干扰的情况下能够保持独立的计算单元。多线程相当于一个并发(concunrrency)系统。并发系般同时执行多个任务。如果多个任务可以共享资源,特别是同时写入某个变量的时候,就需要解决同步的问题。比如,在的多线程布料仿真系统中,所有的

38、质点都有位置、速度、度等属性,当计算其中一个质点的受力的时候,须这个质点相邻的一些质点的位置来计算质点之间弹簧的受力。如果只有一个质点进行计算(即只有一个CPU的时候),则不会发生问题。但是如果多个线时计算质点之间的受力,则质点需要修改自己的位移数据同时其他质点的位移受力等数据。void computeGridSize(un, ublockSize, u&numBlocks, u&numThreads)numThreads = min(blockSize, n);numBlocks = (n % numThreads != 0) ? (n / numThreads + 1) : (n / nu

39、mThreads);就会看到,其根本原因在于同时发生的各个线程都可以对某一个质点的属性进行读取和写入。对于多线程程序来说,同步(synchronization)是指在一定的时间内只允许某一个线程某个资源 。而在此时间内,不允许其它的线程该资源。因此,需要在这个GPU的过程中进行同步。1、线程块内部的同步cuda语言中有一个方法为 syncthreads(),其作用就是令线程块内线步,即多个线程执行相同程序的时候,程序内部出现 syncthread()函数时,所有的线程都会在执行这个语句之后休眠,一直当所有线时进入这个休眠状态之后,线程都会在同一时间被唤醒,然后继续执行接下来的语句。即保证线程会

40、肿的所有线程都执行到同一位置。当整个线程块 syncthreads(),否则造成错误。同一分支时才可以使用因此在整个函数中,线程块内部的程序kernel如下:2、GPU和CPU之间的同步同样的,CPU和GPU都由它们的资源和内存的区域,因此当CPU上的线程和GPU上的线程交叉对方的资源或者内存区域的时候,同样会发生,因此在CPU和GPU之间同样需要线步机制。CPU和GPU并行有两种可能。其中一种可能是对于特殊的负责和GPU交互的线程来说,这可能会杂的情况。比较复/线程中质点获取其他质点的位置等属性/质点通过计算其位置和其他质点的属性之后,计算出该质点在下一个时刻的速度度和位置等属性 synct

41、hreads();/线程之间同步/质点重新修改其位置和速度等属性而另外一种可能则是传统的和GPU无关系的host thread, 这时候它该继续和其他host thread并行,那就会继续并行。这种情况所以,最简单的并行方式就是:在本文中暂时不。多线程(host上), 一个/多个线程在CPU上计算,压榨CPU;一个/多个线程在GPU行算,不用考虑CPU代码能否并行,能否充分利用CPU(由前者负责压榨,这专心交流GPU即可)。所以,在通常的GPU的程序中,都希望由一种简单的运算,因此大部分人在进行GPU之间,会先使用CPU处理复杂的,非并行处理过程,在这个过程,不使用GPU来进行计算。而当面对需

42、要进行大数据量简单的并行计算时,就会使用GPU进行,然后使CPU进行睡眠状态,避免CPU提前进入其他程序而造成资源。当GPU处理完并行程序的时候,再唤醒CPU进行接下来的任务处理。cuda语言中有一个方法为cudaThreadSynchronize(),其主要作用为同步所有设备上的线程,等待所有线程结束。当入这个函数。需要CPU进行计算等待时,就加CPU线程遇到这个指令时,它会进入休眠状态,一直到所有GPU线程处理完它们的数据,CPU线程就会被唤醒,执行接下来的指令。第3章 系统具体的实现和架构已经在上文具体具体阐述了系统使用的主要模型和一些计算所用到的方法,那么,在这一章,具体来阐述使用的数

43、据结构,使用的对象和对象所的一些变量、这些对象所用到的方法。3.1 系统的具体实现步骤对所有计算机仿真都分为具体的步骤有:建模、运动控制、的渲染绘制。建模就是整个计算机绘制的初始化过程,运动控制就是在整个仿真运动过程中对质点和物体进行移动、缩放、旋转的运动控制,描述和计算运动的整个过程,而的渲染和绘制就是将所得到的质点进行颜色纹理、光照计算、阴影计算等最终将网格和模型渲染成逼真的二维图像显示在外设上。而本文中的布料仿真系统中,来,分为以下四个步骤 :1、建模运动控制中的GPU部分单独提取出在建模部分对布料和场景中其他物体例如地板和碰撞球体进行初始化,布料的网格规模,布料之间的弹簧的参数都会进行

44、一些初始化,方便续的计算。2、运动控制后在运动控制部分,就会接触到关于质点的各种相关参数,并根据仿真效果的条件,做出相应的参数改变。并且,在这个运动控制的部分,还会接触到风力的作用、接触到物体时的作用和经过拉扯的时候,布料发生形状上的改变。3、GPU在GPU部分,质点的运动进行时间积分,并对这个过程进行。这个部分将涉及到GPU的内存分配和同步。4、绘制在绘制部分,所有在场景建模的物体进行绘制,包括碰撞的球体、地板和布料。在对布料进行绘制的时候,会加上材质和光照,同时加上纹理。3.2 系统实现的架构布料仿真系统将分为以下几个撞检测、场景设置、交互设计、GPU模块:布料建模、纹理、灯光材质、碰。接

45、下来将分别阐述这些内容。3.2.1 布料建模布料建模是布料仿真系统中比较重要的部分,也是初始化步骤中的主要部分。因为采用的是质点弹簧模型,因此很直观地有质点和弹簧以及布料的类。相关代码如下:在程序中对布料和顶点的绘制如下:/设置顶点的初始位置struct Spring p1, p2;float rest_length; float Ks, Kd;type;GLuclothVAOID, clothVBOVertiID, clothVBOIndiID; vectlm:vec4 X;vectlm:vec4 X_last; vectlm:vec3 F;for( j=0;j=numY;j+) for(

46、i=0;i=numX;i+) Xcount = glm:vec4( (float(i)/(u-1) *2-1)* hsize, sizeX+1, (float(j)/(v-1) )*sizeY),1);X_lastcount = Xcount; count+;/添加结构弹簧,弯曲弹簧和错切弹簧类似for (l1 = 0; l1 v; l1+)/ vfor (l2 = 0; l2 (u - 1); l2+) AddSpring(l1 * u) + l2,(l1 * u) + l2 + 1,KsStruct,KdStruct,STRUCTURAL_SPRING);/ Verticalfor (l1

47、 = 0; l1 (u); l1+)for (l2 = 0; l2 (v - 1); l2+) AddSpring(l2 * u) + l1,(l2 + 1) * u) + l1,KsStruct,KdStruct,STRUCTURAL_SPRING);/绘制布料和布料上的顶点void DrawCloth()glBindVertexArray(clothVAOID);glDrawElements(GL_TRIANGLES, indi.size(),GL_UNSIGNED_SHORT,0); glBindVertexArray(0);特别需要说明的是:OpenGL基本的绘图函数例如glVerte

48、x、glNormal等在调试模式下运行时,如果模型的顶点数或者三角面数过大(比如超过一万时),则程序运行速度会非常慢,根本就无法进行正常的调试。为此查阅了相关资料,找到glArrayElement、 glDrawElements这两个个函数。这两个函数都能通过少数几条语句的调用实现大量数据的绘制,从而节省了函数调用的资源占用。glArrayElement函数用法简单直接,只要把所有的顶点、法向量等数据,按照三角形的顺序准备好,就可以直接渲染,但缺点是不支持顶点索引,所以内存占用比较大。举例来说,如果一个网格有100个顶点,一般大有200个三角面,如果使用glArrayElement就需要200

49、3600个顶点的数据,相比原有的数据多了5倍。如果是已经条带化的数据,这种冗余数据多的可能就不只5倍了。权衡之下还是决定使用glDrawElements函数。如图3-1所示,即为布料网格:void DrawClothPos()glBindVertexArray(clothVAOID);/draw the masses last glDrawArrays(GL_POS, 0, total_pos);glBindVertexArray(0);图3-1 布料仿真系统中的网格在原来的质点弹簧模型中,面片是以四边形的形式存在的,为了避免不共面的情况和加快绘制速度,在绘制过程中采用三角形的方式来绘制,分割

50、三角形的策略就是对所有四边形网格,都以同一个方向划分成两个三角形。3.2.2 纹理和灯光材质的设置对灯光材质的设置:glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST);GLfloat ambient4=0.25f,0.25f,0.25f,0.25f; GLfloat diffuse4=1,1,1,1;GLfloat mat_diffuse4=0.5f,0.5f,0.5f,0.5f; GLfloat4=0,0,1,0;glLightfv(GL_LIGHT0, GL_ITION,); glLightfv(GL_LI

51、GHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);用glLightfv()方法分别设置了灯光的位置,漫反射属性和环境光属性。然后用glMaterialfv()简单设置了材质属性。关于纹理:纹理是真实感图形制作的一个重要部分,使用 OpenGL 提供的纹理图像贴图函数,将与多边形进行拟合,可以方便的制作真实感图形,而不必花的时间去考虑物体的表面纹理。所以利用这种机制来实现物件上的动态变化,从而在物体上模拟动画的方式。在给网格贴上纹理之前,是将网格上的顶点和所需要的须给网格和所要添加的进行纹理,就之间进行坐标

52、的一一对应,这样再在网格之间的点做一个线性插值。这样,一张完整的就被贴到了网格上面。在绘制纹理场景时,不仅要给出每个顶点定义的几何坐标,同时还要定义纹理坐标。经过几次变换之后,几何坐标决定顶点在屏幕上的绘制位置,而纹理坐标决定纹理图像中的哪一个元素赋予该顶点。纹理相关程序如下:for(size_t i=0;itotal_pos;i+) Vertex& t = vertii;t.uv.x = (float(Xi.x+hsize)/ float(size) *10.0f; t.uv.y = (float(Xi.z)/float(size) *10.0f;glEnableCntSe(GL_VERTE

53、X_ARRAY);在 OpenGL 中,定义纹理坐标的函数是 glTexCoord*()。不过在一些情况下(多用于环境 的情况)。为获得特殊效果需要自动生成纹理数据,并不要求为物体的顶点赋予纹理坐标。自动生成纹理坐标的函数 glTexGen()。glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_diffuse);glDisable(GL_LIGHTING);3.2.2 关于场景中碰撞球体和地板的建模绘制地板就是由在同一个y轴坐标的网格的,同理,场景中的碰撞球体也是由一个个面片沿着球体的经线一个个绘制而成。在opengl中,有将球体绘制封装好的

54、方法,glutWireSphere是GLUT工具包中的一个函数。该函数用于渲染一个球体(由线条 球体)。球体球心位于原点。在OpenGL中默认的原点就是窗口客户区的中心。图3-1就展示了碰撞球体和地板。而如果需要画一个椭球,就需要在正球体的基础上进行线性变换,我们在绘制之前先给整个场景做一个矩阵变换:glm:mat4 ellipsoid, inverse_ellipsoid;ellipsoid = glm:translate(glm:mat4(1),glm:vec3(0,2,0); ellipsoid = glm:roe(ellipsoid, 45.0f ,glm:vec3(1,0,0);el

55、lipsoid = glm:scale(ellipsoid, glm:vec3(fRadius,fRadius,fRadius/2); inverse_ellipsoid = glm:inverse(ellipsoid);/绘制椭球 glColor3f(0,1,0);glEnableCntSe(GL_TEXTURE_COORD_ARRAY); glEnableCntSe(GL_NORMAL_ARRAY);glVertexPoer(3, GL_FLOAT,sizeof(Vertex), &verti0.); glTexCoordPoer(2, GL_FLOAT,sizeof(Vertex), &

56、verti0.uv);glNormalPoer(GL_FLOAT,sizeof(Vertex), &verti0.n); glDrawElements(GL_TRIANGLES, indi.size(), GL_UNSIGNED_SHORT ,&indi0);glDisableCntSe(GL_NORMAL_ARRAY); glDisableCntSe(GL_TEXTURE_COORD_ARRAY); glDisableCntSe(GL_VERTEX_ARRAY);3.2.3 关于场景中碰撞球体的碰撞检测在计算正球体是否和布料上的质点发生碰撞的时候,是计算质点和球心之间的距离,如果距离小于球体

57、半径,那么就可以判断他们之间发生了碰撞。但是面对一个椭球,如何判断它时候和布料上的质点发生碰撞呢?是将一个正球体做一个线性变换得到的椭球,那么,布料上的质点做一个逆变换,那么质点和一个正球体,于是得到一个变形的空间,这个空间中存在的是变形的变形的质点与正球体之间做一个距离上的差值,然后判断和正球体半径的大小关系,从而得出质点是否和球体之间发生了碰撞。相关代码如下:void EllipsoidColli() for(size_t i=0;itotal_pos;i+) glm:vec4 X_0 = (inverse_ellipsoid*glm:vec4(Xi,1); glm:vec3 delta0

58、 = glm:vec3(X_0.x, X_0.y, X_0.z) - center; float distance = glm:length(delta0);if (distance 1.0f) delta0 = (radius - distance) * delta0 / distance;/ Transform the delta back to original space glm:vec3 delta;glm:vec3 transformInv;transformInv = glm:vec3(ellipsoid0.x, ellipsoid1.x, ellipsoid2.x); tran

59、sformInv /= glm:dot(transformInv, transformInv);glPushMatrix(); glMultMatrixf(glm:value_ptr(ellipsoid); glutWireSphere(fRadius, iSli, iStacks); glPopMatrix();和地板之间的碰撞检测和处理:3.2.4 布料仿真系统中的交互设计在本文中的布料仿真系统中,添加了鼠标拖拽的交互方式。当在屏幕的中的画面上点击的时候,一条射线做一个对应,那么,就发出一条射线,将如何知道,三在屏幕上的点和三上的一点是这条射线上的哪屏幕上这个点的深度缓存。一个点呢?首先得

60、知道这个点的深度,然后所谓深度,就是在openGL坐标系中,像素点Z坐标距离摄像机的距离。摄像机可能放在坐标系的任何位置,那么,就不能简单的说Z数值越大或越小,就是越靠近摄像机。if (Xi.y = -WORLD_SIZE/2.0 + 0.5) Xi.y = -WORLD_SIZE/2.0 + 0.5;multiplyVectorScalar(Xi.v, 0, &(Xi.v);delta.x = glm:dot(delta0, transformInv);transformInv = glm:vec3(ellipsoid0.y, ellipsoid1.y, ellipsoid2.y); tra

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论