旅游仿真软件技术纲要Word文件下载.docx
《旅游仿真软件技术纲要Word文件下载.docx》由会员分享,可在线阅读,更多相关《旅游仿真软件技术纲要Word文件下载.docx(11页珍藏版)》请在冰点文库上搜索。
由于没有使用层次模型,获得模型网格顶点在世界坐标中位置的计算量也很小。
但是,这类动画的适应性很弱,角色很难通过实时计算来与环境进行良好的互动,以获得预先存储的动画序列之外的动画效果。
另一方面,由于关键帧要存储网格模型所有的顶点信息,动画文件占用的空间比较大。
第三类是骨骼蒙皮动画(SkinnedMesh)。
骨骼蒙皮动画可以看作是关节动画和渐变动画的结合。
同时兼有关节动画的灵活和渐变动画的逼真。
这里的骨骼蒙皮动画特指skinndmesh,也叫骨骼动画。
无论是合金装备,波斯王子,还是魔兽世界,到处都是骨骼动画技术的运用。
用它塑造了各种各样,栩栩如生的生物。
其中,人类体格的骨骼动画运用最为广泛。
从本质上来讲,所有的3D角色动画系统都是基于一种逻辑,就是用一定的方法去改变Mesh顶点的位置。
骨骼动画的基本原理就是首先控制各个骨骼和关节,在上面的skinnedmesh与其匹配。
在骨骼蒙皮动画中,一个角色由作为皮肤的单一网格模型和按照一定层次组织起来的骨骼组成。
骨骼层次描述了角色的结构,就像关节动画中的不同部分一样,骨骼蒙皮动画中的骨骼按照角色的特点组成一个层次结构。
相邻的骨骼通过关节相连,并且可以作相对的运动。
通过改变相邻骨骼间的夹角,位移,组成角色的骨骼就可以做出不同的动作,实现不同的动画效果。
皮肤则作为一个网格蒙在骨骼之上,规定角色的外观。
这里的皮肤不是固定不变的刚性网格,而是可以在骨骼影响下变化的一个可变形网格。
组成皮肤的每一个顶点都会受到一个或者多个骨骼的影响。
在顶点受到多个骨骼影响的情况下,不同的骨骼按照与顶点的几何,物理关系确定对该顶点的影响权重,这一权重可以通过建模软件计算,也可以手工设置。
通过计算影响该顶点的不同骨骼对它影响的加权和就可以得到该顶点在世界坐标系中的正确位置。
动画文件中的关键帧一般保存着骨骼的位置,朝向等信息。
通过在动画序列中相邻的两个关键帧间插值可以确定某一时刻各个骨骼的新位置和新朝向。
然后按照皮肤网格各个顶点中保存的影响它的骨骼索引和相应的权重信息可以计算出该顶点的新位置。
这样就实现了在骨骼驱动下的单一皮肤网格变形动画。
或者简单地说骨骼蒙皮动画。
骨骼蒙皮动画的效果比关节动画和单一网格动画更逼真,更生动。
而且,随着3D硬件性能的提高,越来越多的相关计算可以通过硬件来完成,骨骼蒙皮动画已经成为各类实时动画应用中使用最广泛的动画技术。
骨骼蒙皮动画的一些技术细节,在一个典型的骨骼蒙皮动画模型文件中,会保存如下信息:
网格信息,骨骼信息和动画信息。
网格信息是角色的多边形模型。
该多边形模型一般由三角形面片组成,每一三角形面片有三个指向模型的顶点表的索引。
通过该索引,可以确定该三角形的三个顶点。
顶点表中的每一顶点除了带有位置,法向量,材质,纹理等基本信息外,还会指出有哪些骨骼影响了该顶点,影响权重又是多少。
影响一个顶点的最大骨骼数一般取决于模型的设计和目标硬件平台的限制。
例如,对于一个典型的人体骨架,一般只有在关节附近的顶点才会受到相邻几块骨骼的影响,而同时影响某一顶点的骨骼数,也不会超过四块。
骨骼信息包括全部骨骼的数量和每一骨骼的具体信息。
所有的骨骼按照父子关系组织成一棵树。
树根代表整个骨架,其余每一节点包括叶子节点代表一根骨骼。
每一根骨骼包括该骨骼在父骨骼坐标系中的变换矩阵,通过该变化矩阵确定了该骨骼在父骨骼坐标系中的位置。
在动画信息中则保存了若干关键帧。
每一关键帧指出了每一骨骼在该时刻相对于父骨骼坐标系的变换矩阵,当然也可以是该骨骼相对于父骨骼的位置,朝向等变动。
在播放动画序列中的任一时刻:
1)首先确定该时刻之前和之后的两个关键帧,然后按照该时刻与前后两个关键帧时刻的时间值插值计算出该时刻该骨骼相对于父骨骼的新变换矩阵,这个变换矩阵往往代表旋转变换,放缩变换也能接受,如果是平移变换矩阵,很容易将Mesh四分五裂。
2)对于皮肤网格中的每一个顶点,计算它在世界坐标中新的位置和朝向。
首先找到影响该顶点的所有骨骼。
然后计算每一骨骼对该顶点的影响。
也就时说,计算在该骨骼独立作用下顶点的新位置。
计算按照如下公式:
顶点的新位置=最初状态顶点的位置*最初状态骨骼世界变换矩阵的逆矩阵*骨骼的新变换矩阵(I)
然后将所有这些新位置按照每一骨骼的影响权重加权求和。
注意所有权重的和应该恰好为1。
在公式(I)中,骨骼的新变换矩阵是相对于父骨骼变换的,另一方面这个新变换矩阵是世界变换矩阵,它的任何变换是相对于世界坐标系原点的。
因此需要把最初状态顶点移动到相当于父骨骼节点是原点的位置上,再进行矩阵变换。
3)根据网格模型顶点的新位置和朝向绘制角色网格。
2骨骼蒙皮动画技术
2.1在一个典型的骨骼蒙皮动画模型文件中,会保存如下信息:
*网格信息是角色的多边形模型。
*索引,可以确定该三角形的三个顶点。
*影响一个顶点的最大骨骼数一般取决于模型的设计和目标硬件平台的限制。
1)首先确定该时刻之前和之后的两个关键帧,然后按照该时刻与前后两个关键帧时刻的时间值插值计算出该时刻该骨骼相对于父骨骼的新位置,新朝向,新变换矩阵等等。
2)然后从根骨骼开始遍历骨架,计算每一个骨骼相对于世界坐标的变换矩阵。
计算该矩阵是一个递归过程,用伪码描述如下:
CalcBoneWorldMarix(pCurBone,pParentBone)
{
pCurBone->
WorldMatrix=pParentBone->
WorldMatrix*
LocalMatrix;
pChildBone=pCurBone->
pFirstChildBone;
while(pChildBone)
CalcBoneWorldMatrix(pChildBone,pCurBone);
PChildBone=pChildBone->
pNextSiblingBone;
}
3)对于皮肤网格中的每一个顶点,计算它在世界坐标中新的位置和朝向。
先找到影响该顶点的所有骨骼。
计算在该骨骼独立作用下顶点的新位置。
顶点的新位置=骨骼的世界变换矩阵*最初状态骨骼世界变矩阵的逆矩阵*最初状态顶点的位置(I)
在公式(I)中,最初状态顶点的位置首先要与最初状态骨骼世界变矩阵的逆矩阵相乘是因为骨骼的世界变换矩阵是将骨骼从世界坐标系的原点移动到它在某一时刻所处的新位置,相应的,它所控制的顶点也应该是从包围位于原点位置的骨骼的那一位置移动到新位置。
而最初状态顶点的位置已经被最初状态骨骼世界变矩阵移动到了世界坐标系中的某一点,为此,必须要首先把这一顶点连同控制它的最初状态骨骼一起移回到世界坐标系的原点。
顶点朝向按照相同方式计算,但是不考虑平移效果。
4)根据网格模型顶点的新位置和朝向绘制角色网格。
2.2硬件支持
观察骨骼蒙动画的计算过程可以发现,在一个顶点受到许多骨骼影响的时候,求一个顶点的新位置会牵涉到大量的矩阵与乘法运算。
比如如果一个顶点受到16根骨骼的影响,那么就要进行16次矩阵与向量相乘的运算,然后乘以影响权重又需要16次浮点数相乘,最后还需要15次浮点数相加来求得最终的顶点位置。
对于一个复杂的角色模型,比如精细的人体模型,上万的顶点数和同时有几十根影响骨骼并不少见。
骨骼蒙皮动画过大的计算量一度限制了它的广泛应用。
幸运的是,随着3D硬件技术加速的发展,特别是硬件支持的VertexShader的出现,这一情况得到了很大的改观。
2001年nVidia公司推出了突破性的三维加速卡GeForce3,介绍了VertexShader和PixelShader这两个重要的功能,把开发者从T&
L的固定渲染流水线中解放出来。
因此,这两个Shader功能又常被称作可编程渲染流水线。
一个Shader程序本质上是一段由应用开发者编写,运行在3D加速卡上的短小程序。
这段程序可以使用汇编语言编写,也可以使用高级语言编写,但最终都要由相关的工具转换成机器代码,然后由3D加速卡在渲染图形时运行。
VertexShader程序对顶点进行处理,PixelShader则对纹素进行处理。
在渲染一个场景的时候,用户可以设定当前VertexShader程序,设定该Shader程序使用的常量(比如世界观察变换矩阵)。
之后在渲染的过程中,每一个顶点都会经过该Shader程序的处理,而该Shader程序每次也只能处理一个顶点。
当用户不准备使用一些通用的3DAPI(比如OpenGL,Direct3D)提供的变换和光照计算功能的时候——虽然这些计算现在也是由加速卡完成的——就可以自己编写VertexShader程序来完成这个功能。
***在Direct3D8.1中,VertexShader处理器提供了一个整数地址寄存器a0.x,96个常量寄存器,12个临时寄存器,16个顶点寄存器作为输入寄存器以及输出寄存器oD0,oD1,oFog,oPos,oPts,oTo–oT7。
除了a0.x和oPts,其余所有的寄存器都具有四个浮点分量,可以用x,y,z,w来访问。
VertexShader处理器还提供了若干汇编指令。
更详细的说明可以参考Direct3D参考手册。
在渲染每一帧时,计算每一根骨骼对顶点的影响和求这些影响的加权和可以完全通过VertexShader程序来完成,同时VertexShader程序也还要完成光照计算以及实现其它顶点效果所需要的计算。
PixelShader不是实现骨骼蒙皮动画所必需的。
要使用VertexShader来实现骨骼蒙皮动画的计算,首先要把每一根骨骼的变换矩阵(骨骼的世界变换矩阵*最初状态骨骼世界变矩阵的逆矩阵)写入3D加速卡的常量寄存器中。
由于每一根骨骼对应的变换矩阵有4X4共16个浮点数,因此每一骨骼需要4个常量寄存器(事实上可以只存储前三行元素,这样就只需要3个常量寄存器。
这样不考虑其它常量所需要的常量寄存器,比如材质,透视变换矩阵,光源等等,一个Shader中可以访问的最大骨骼数不会超过96/3=32块。
因此对于一个使用了大量骨骼的角色,就需要分别渲染使用了不超过32块的同一骨骼集的不同部分)。
然后交给VertexShader程序处理的每一个顶点还需要包括使用哪几根骨骼的信息(也就是指出使用哪一个常量寄存器的中保存的变换矩阵。
)同时影响一个顶点的骨骼数同样受到硬件的限制,对于Direct3D8.1来说,这一数字是4。
顶点信息还应包括影响该顶点的每一块骨骼的影响权重。
由于所有权重的和应该等于1,所以最后一块骨骼的影响权重可以通过计算获得,无需包含在顶点信息内。
VertexShader程序在收到一个顶点后,会按照该顶点骨骼索引利用a0.x寄存器一一定位相应的骨骼变换矩阵,然后对顶点位置进行变换,然后乘以相应骨骼的影响权重,最后把求得的变换结果累加,这样就得到了最终顶点的新位置。
2.3SkeAni的实现
SkeAni是一个简单的骨骼蒙皮动画演示程序。
该程序使了用Direct3D8.1提供了VertexShader功能和显卡的3D加速功能。
SkeAni由三部分组成:
SkeAni演示程序SkeAni.exe,模型文件modal.saf和VertexShader程序skeani.vsh。
SkeAni使用了Direct3D提供的D3DFramework来简化与Direct3DAPI的接口。
与骨骼蒙皮动画相关的代码位于SkeAni.cpp和SkeAni.h两个文件之中。
这两个文件完成读取模型文件,初始化内部状态,插值计算某一时刻骨骼所对应的局部变换矩阵和世界变换矩阵,设置VertexShader中的骨骼世界变换矩阵与其它常量,设置渲染状态和渲染网格模型等功能。
计算每一顶点的新位置和相应的光照则由VertexShader程序skeani.vsh来完成。
Modal.saf是SkeAni所使用的模型文件。
该模型文件包含了四部分信息:
场景基本信息,骨骼信息,网格信息和动画信息。
场景基本信息指出了模型在世界坐标系中的位置。
骨骼信息指出了骨骼的数量,骨骼间的层次关系,每一骨骼相对于父骨骼的变换矩阵,每一骨骼最初状态世界变换矩阵的逆矩阵。
网格信息指出了顶点数,三角形面片数,顶点表,面片顶点索引表和影响网格的骨骼数与骨骼名称。
动画信息指出了动画序列数和动画序列。
每一动画序列控制一块骨骼,它包含了一系列的关键帧。
每一关键帧指出了关键帧对应的时间和变换矩阵,这一矩阵将赋给所影响骨骼的局部变化矩阵以实现骨骼的动画。
Modal.saf中的网格是一个由三角形面片组成的长方体。
该模型中一共有4块骨骼,其中有3块骨骼影响网格,而同一时间最多只有2块骨骼影响一个顶点。
Modal.saf用如下方法获得。
首先在3DSMAX中利用基本建模功能和CharacterStudio的Physique功能制作一个场景与相关动画,然后通过Direct3D附带的XSkinExp插件输出为X文件,然后修改Direct3D附带的例子SkinnedMesh将从X文件中解码出来的各类数据写入Modal.saf。
具体的读取Modsl.saf文件的代码可以参考SkeAni.cpp中的CSkeAniApp:
:
LoadSkeAniModal函数。
SkeAni演示程序代码的代码执行流程如下:
CSkeAniApp:
RestoreDeviceObjects设置渲染状态,创建VertexShader程序,在
C2常量寄存器中设置透视变化矩阵,在C1常量寄存器中设置一个光源。
。
D3DFramework的Render3DEnvironment执行,开始渲染一帧。
Render3DEnvironment调用CSkeAniApp:
FrameMove
FrameMove获得当前时间。
FrameMove以当前时间作为参数调用CSkeAniApp:
Animate
Animate遍历每一个动画序列,插值计算该动画序列所对应的骨骼对应当前时间的本地变换矩阵Render3DEnvironmentCSkeAniApp:
Render
Render调用CSkeAniApp:
CalculateBonesWorldMatrices计算根骨骼的世界变化矩阵
CalculateBonesWorldMatrices递归调用自身以计算所有骨骼的世界变化矩阵
。
Render初始化渲染状态,设置当前VertexShader。
Render计算然后从C9开始连续设置3个骨骼的世界-视变换矩阵
Render设置光照与骨骼索引计算所需要的VertexShader常量
Render调用DrawIndexedPrimitive进行绘制,此时skeani.vsh会被3D卡执行以计算顶点的新位置和光照效果。
Skeani.vsh是SkeAni所使用的VertexShader程序的源程序。
SkeAni读取,编译该源程序,然后创建VertexShader渲染所需的程序,在需要的时候,设置此VertexShader程序为当前VertexShader程序,这时候,系统的固定几何变换与光照流水线会被关闭。
VertexShader必须完成相应的几何变换与光照计算。
Skeani.vsh基于D3D例子SkinnedMesh中的skinmesh2.vsh,略有修改。
其工作原理如下:
首先执行第一条语句计算影响该顶点的骨骼在常量寄存器中的索引。
执行完该条语句后,r1.x保存的是影响顶点的第一根骨骼的变换矩阵的常量寄存器索引,r1.y则保存着第二根骨骼的索引。
然后执行第二,第三条语句计算第二根骨骼的权重,该权重将保存在r0.w中。
然后第四至第六条语句用第一根骨骼改变该顶点的位置和朝向。
第七,第八条语句将结果乘以第一根骨骼的权重。
这样,r4,45分别保存第一根骨骼对顶点的位置和朝向的影响。
第九至第十三条语句计算第二根骨骼的对顶点的影响并且累加到r4,r5寄存器。
第十四和第十五条语句对顶点进行投影运算,然后将顶点得归一化投影坐标通过oPos输出。
第十六至第十八条语句归一化顶点的法向量,为后面的光照计算作准备。
最后几条语句则计算泛光和镜面高光然后通过oD0,oD1输出。
VertexShader的输出结果将会交给渲染流水线的后续功能部件进行处理并最终在屏幕上显示出来。
由此便实现了硬件支持下的骨骼蒙皮动画。
3骨骼蒙皮动画的软件实现
Maya4.0骨骼动画-骨骼蒙皮
对于三维人物动画而言,首先是使用建模工具创建模型,然后创建人物模型的骨骼,接下来便是将模型与骨骼绑定在一起,绑定的过程称为“蒙皮”。
骨骼被蒙皮后,可以使人物的模型随骨骼一起运动,并在骨骼运动时产生相应的变形。
骨骼在蒙皮过程中,所处的姿势称为BindPose。
蒙皮后,骨骼的运动会引起皮肤的变形。
但是,有时会出现不恰当的变形,这就需要对骨骼或皮肤做相应的修改,此时可以运用相关命令使骨骼恢复绑定姿势,然后断开骨骼与皮肤之间的关联。
在Maya中,可以随时把骨骼和皮肤断开或重新连接。
详细见Maya教程
3D角色动画技术和其它动画技术相结合,就能创造出绚丽多彩的游戏世界。
附件33D旅游软件引擎与美工设计技术方案
13D引擎
引擎需要提供的包括:
曲面(curvedsurfaces)、动态光线(dynamiclighting)、体雾(volumetricfog)、镜面(mirrors)、入口(portals)、天空体(skyboxes)、节点阴影(vertexshaders)、粒子系统(particlesystems)、静态网格模型(staticmeshmodels)、网格模型动画(animatedmeshmodels)
具备完整功能的3D游戏引擎所需要的基本部件:
称为系统(System)、控制台(Console)、支持(Support),渲染/引擎内核(Renderer/EngineCore)、游戏介质层(GameInterface)、以及工具/数据(Tools/Data)。
1.1基本部件
Tools/Data(工具/数据)
在开发过程中,需要3d模型编辑器,关卡编辑器,以及图形程序。
分为购买,免费的程序,自己动手去写。
名称
简介
说明
3d模型编辑器
建立3D模型
3DMAX8等
关卡编辑器
自行设计编写
转换器或是插件
3d模型格式转换成自有的格式等
自行设计编写可第三方软件
其它游戏数据工具
如可见度估算或是光线贴图
估计好自己的工具与设计出自己的工具可以为自己拥有的引擎有强大特性。
利用的第3方工具辅助开发,必须注意:
引擎发布为opensouce或是允许修改。
另一方面,应该花大量时间去设计美术,关卡,音效,音乐和实体模型。
System(系统)
系统(system)是引擎与机器本身用做通信交互的部件。
一个优秀的引擎在不同平台移植时,系统是唯一需要做主要更改(扩加代码)的地方。
系统可分为若干个子系统,其中包括:
图形(Graphics)、输入(Input)、声音(Sound)、记时器(Timer)、配置(Configuration)。
主系统负责初始化、更新、以及关闭所有的子系统。
图形子系统(GraphicsSub-System)一般地讲,图形子系统都是利用OpenGL、Direct3D,Glide或是软件渲染(softwarerendering)实现。
更理想些,形成通用的API,并抽象出一个“图形层”并将它置与实现API之上,以获取最好的兼容性、最佳的表现效果。
输入子系统(InputSub-System)把各种不同输入装置(键盘、鼠标、游戏板[Gamepad],游戏手柄[Joystick])的输入触发做统一的控制接收处理。
例如,在游戏中,系统要检测玩家的位置是否在向前移动,与其直接地分别检测每一种输入装置,不如通过向输入子系统发送请求以获取输入信息,这样用户与玩家可以非常自由地切换输入装置,通过不同的输入装置来获取统一的行为将变的很容易。
声音子系统(soundsystem)负责载入、播放声音。
当前很多游戏都支持3D声音,但实现稍许复杂一些。
“时间系统”(time)3D游戏引擎中很多出色的表现都是基于“时间系统”(time)的。
一份合理的设计将会避免为实现而撰写大量雷同的控制代码;
配置系统(Configuration)位于所有子系统的顶端。
负责读取配置记录文件,命令行参数,或是实现修改设置(setup)。
在系统初始化以及运行期间,所有子系统都将一直与它保持通讯。
切换图象解析度(resolution),色深(colordepth),定义按钮(keybindings),声音支持选项(soundsupportoptions),甚至包括载入游戏,该系统将