方案
1. 技术方案
(1) 系统概要
SI Engine是基于Direct9c和.Net体系结构的用于PC机实时图形应用和游戏的开发平台。该平台包括两个主要部分。一是实时图形应用的开发制作系统,一是支持实时图形运行的虚拟机。SI Engine的设计以追求图形应用的效果和效率为主要的目标。以系统的通用性、开放性、易用性为次要目标。力求做一个满足制作高效的、逼真的实时图形应用要求的通用的三维实时图形开发平台。
两部分系统的协同模式如下:
开发制作系统通过制作者的交互编辑来定义实时图形应用的交互脚本和资源文件,并将这些生成的脚本和资源汇总成游戏和图形应用的关卡文件。供虚拟机解析和调用。
关卡文件是以命令数据流的形式组织的,关卡文件可以解析成一组时序的命令块以及跟在命令块后面的用于执行命令所需要的数据块组成。
虚拟机解析关卡文件,并执行关卡文件中的命令来完成建立图形场景,建立交互界面,编译交互脚本,启动场景交互等工作。以生成并运行关卡文件中定义的图形应用。如图:
关卡文件实际上描述一个游戏的一个关卡。通常一个游戏有很多的关卡。
SI Engine是一个具有革命性的平台,他的创新体现在绘图上是优异的场景简化和渲染管理体系结构、对新渲染算法的充分支持、以及可自扩展渲染算法的体系结构。体现在人工智能和物理特效上是其总结了游戏中人工智能和物理运算的常用情况并提供了相应的API。体现在网络上是提供了游戏网络服务的集群负载平衡体系结构。体现在音频和视频上是其支持了空间音效、文语转化、纹理视频、视音频即时通信。体现在通用性上是其跳出了游戏引擎必须针对特定类型游戏设计的框框使其应用范围几乎覆盖目前所有类型的游戏和实时图形应用。体现在易用性上是其提出了敏捷的智能的可视化的设计游戏软件的概念并提供了可视化的制作平台。体现在开放性上是其支持动态可扩展类的脚本体系结构允许通过脚本修改引擎的原始设计扩展引擎功能。
(2) 引擎内核虚拟机体系结构
SI Engine内核包括以下几个部分:
关卡解析
线程管理
对象管理
脚本引擎
界面交互
图形绘制
物理运算
音频解码
视频解码
人工智能
网络通信
A. 关卡解析:
负责从关卡文件中,获取命令和数据。并执行命令和数据以创建游戏场景。
关卡解析的体系结构类似于一个自动机,自动机包括一个读取头用来读取一次一个数据块或命令块。一个数据队列保存读取的数据块和一个命令队列保存读取的命令块。一个内部状态机根据命令堆栈顶的命令块中的命令代码做内部的状态转换并执行命令。自动机的状态图如下:
B. 线程管理:
负责运行线程、解析线程、网络线程、绘图线程,交互线程、音频线程、视频线程、用户后台线程的同步和管理。
C. 对象管理:
负责管理内存对象和资源。并用树状结构索引。以方便脚本对内存对象进行修改和调用。提供访问,检索,管理,对象和资源的函数和接口。
D. 脚本引擎:
是一个基于.Net运行时编译技术的脚本解析系统。系统实现脚本的编译和执行。脚本引擎接受用C#语言书写的脚本。将其编译成动态库文件。为了快速的执行脚本,已经编译的脚本动态库可以直接的载入并执行。
E. 界面交互:
界面交互系统由GUI交互系统,场景事件系统,物理事件系统,时钟事件系统,硬件交互系统、活动响映系统、帧同步事件系统,音视频事件系统,网络事件系统,线程信号灯响应系统组成。
其中GUI交互系统由大量的2D图形控件和控件对于系统事件传递和处理的代码组成。GUI系统从Windows消息循环中获取消息,并将系统消息分发给特定图形控件,调用由脚本定义的消息响应代码处理消息来实现界面的交互。由于常规的Windows基于GDI的图形控件在3D窗口中显示和处理有效率和显示错误的问题。所以系统用Direct3D的绘制技术仿照常规控件的响应方式和外观重写高速的基于3D图形技术的控件。并定义一套控件结构以让用户可以自由的扩展控件功能和自定义控件。
场景事件系统响应场景物体的鼠标拾取拖放、物体的碰撞检测、物体位置的改变、摄相机改变事件。场景事件系统同场景相关,他根据场景待检测事件表,来判断需要检测那些场景事件,和在什么时候检测场景事件。用户可以通过交互脚本来添加和修改场景事件待检测事件表。并设定在什么时间或多少间隔帧检测场景事件。
物理事件系统同场景事件系统一样,检测设定的物理事件,如物理对象的速度改变,加速度改变,受力改变,动能改变,动量改变,质量改变,物理碰撞,物理属性改变等等事件。
时钟事件系统处理系统时钟事件。系统根据设定的事件时序表的设置在系统特定时刻发送特定的时间事件。
硬件交互系统:处理非鼠标和键盘的硬件事件,如游戏控制器事件,物理计算卡事件,3D眼镜事件等等。
活动响应系统负责管理自定义活动的响应。所谓活动是指的一个用户定义的行为和事件响应自动机线程,包括自定义的一组状态,每个状态要响应或发出什么事件或发生某种对象数据操作,以及状态之间的转化条件和线程的停机条件。比如:用户定义在用户按下左键的时候从初始状态激发活动线程x, 活动线程x让角色A开始挥刀动画,如果在动画过程中发生刀和角色B的碰撞那么,角色B执行痛苦动画,角色B的生命力降低,向角色B发送受伤消息,活动线程x本次激发结束返回初试状态。活动响应系统检索自定义活动表,在特定事件激发下开启特定活动的执行线程。
帧同步事件响应系统负责响应绘图系统在绘制特定序号或周期帧时候发出的事件。
音视频事件响应系统负责响应音频和视频系统的事件,如缓冲区中音视频数据播放到特定位置,音视频时间同步事件等等。
网络事件系统响应和处理网络上接受到的事件。
线程信号灯响应系统处理线程间的信号灯事件。
F. 图形绘制:
图形绘制是引擎的核心系统。介于绘制高质量三维图形场景所产生的:数据量大、数据吞吐频繁、硬件资源占用大、渲染算法复杂多样。图形绘制系统需要建立合理的渲染管理系统对场景数据进行合理而高效的规划、管理、裁减。建立合理的内存管理机制以应付海量数据的调度和存储。建立合理的设备分配机制对CPU,GPU等硬件设备进行合理的分配。也要求在保证质量的情况选用尽量高效的渲染算法。并需要针对渲染算法多样性的特点解决各种渲染算法之间兼容性的难题,同时不同的渲染算法对于系统硬件的处理能力和功能的要求也各不相同,而且基于国内外用户现实的硬件多样性环境,要求系统能够测试目标用户平台的功能配置并针对不同的平台配置选用不同质量的渲染算法。并且开发图形运用通常需要对系统进行多次的调试和有针对性的优化所以一个调试和基准测试工具也必不可少。
基于以上需求,引擎图形绘制系统的主要工作分为:
场景管理
资源管理
渲染管理
动画播放
调试和基准测试几个部分。
1) 场景管理系统:
场景管理是游戏引擎图形渲染的核心,他的目标是:在保证不明显降低场景的显示输出质量的情况下尽量简化场景物体的表示和他们的着色属性以减小渲染场景的算法时间和空间复杂度,并同时减少绘制场景物体所占用的设备资源和处理时间。
衡量场景的显示输出质量通常需要一个基准,目前这个基准可以取未经简化的场景的渲染输出图片同简化了的场景的渲染输出图片之间的相素色差。表示为:Delta(x,y)=Image未简化场景(x,y)-Image简化后场景(x,y)
而可以取对整个输出图象的每个像素差的平方和或绝对值和作为衡量简化算法对图象质量影响程度的指标。表示为
质量损失程度=∑|Delta(x,y)| 或质量损失程度=∑(Delta(x,y))^2为了计算的简化通常取前一个为衡量标准。
根据认知心理学的理论我们可以注意到对于输出场景图片,游戏玩家的感兴趣区域常常有一个集中区域。而对于玩家注意力集中区域外的场景输出对玩家游戏真实感的影响不是很大。所以这个指标可以用区域注意力影响函数修改为:
质量损失程度=∑|Delta(x,y)*w(x,y)| 其中w(x,y)为输出图片中每个位置的精细程度对于玩家视觉感受的影响程度权值。我们可以推理在实际的显示输出情况下屏幕中心的显示精细程度对玩家视觉感受的影响大于屏幕边角的影响,所以w(x,y)可以通常可以视为一个以图象中心为中心的2D高斯分布函数。
这样经过对游戏玩家体验的实验,如果我们可以确定在一定游戏图象质量的损失程度范围内对游戏玩家的心理影响不大,那么我们可以以这个损失范围为基准选择场景简化算法。
游戏场景的有损简化算法很多都基于上述的理论。其中有MIP贴图算法、有损几何压缩算法、LOD算法,法线贴图压缩算法等等。
同时我们还可以注意到一些游戏场景的组成元素或场景物体,由于其处于可视范围之外或被遮挡等原因对于最终的场景图片的渲染没有贡献,可以被动态的剔除掉。而剔除掉这些对场景显示没有贡献的场景元素可以加快渲染和绘制场景的速度。基于这样理论的算法就是质量无损的场景简化算法。这些算法通常有视域剪裁算法、闭合测试算法等等。所谓视域裁减算法就是要根据可视区域的位置和大小裁减掉不在可视区域内的物体的绘制。所谓闭合测试算法就是要根据场景元素和物体的遮挡关系,剔出被遮挡的场景元素的绘制。有一些裁减算法往往同时做了视域裁减和闭合测试,如门裁减所以这一类算法统称为裁减算法。
还有一类场景简化算法基于这样的一个共识:显示设备处理场景元素的不同排列方式和不同拓扑结构的效率不同以及显示设备对于用不同数据大小表示的场景数据的处理速度不同。由此产生了一组算法,他们针对显示设备的处理效率对场景元素的拓扑结构和排列顺序进行优化。在保证于元场景同构的情况下加快场景的绘制。通常这类的算法有:无损几何压缩、二叉树算法等等。
衡量场景管理算法不能光依靠场景质量损失这样一个指标,因为场景简化的目的是要加快实时渲染的效率,所以必须考虑其性能指标。
任何场景管理算法都需要占用一定的设备时间来完成场景简化的任务,所以对最终渲染效率的影响除了与场景元素的简化能力有关外还于场景管理算法的效率和频繁程度有关。衡量场景算法的效率可以通过指标:
场景管理效率=(未简化场景的每帧图形渲染时间)/(场景算法执行时间/调用场景简化算法的平均帧间隔+简化后场景的平均每帧图形的渲染时间)
只有在保证质量损失小于可以接受的损失范围下并且场景管理效率大于1的场景简化算法才是有意义的。同时保证图形质量情况下场景管理的效率要越大越好。
同时由认知心理学可以知道只有当动画的帧速率>=30帧/秒,动画才会被视为连续的。这给出了场景简化算法处理时间的底线也就是:
(场景算法执行时间/调用场景简化算法的平均帧间隔+简化后场景的平均每帧图形的渲染时间)<=1/30秒
上面的理论为SI引擎的场景管理指明了方向。
借鉴很多第一人称漫游3D游戏引擎我们可以知道:游戏场景通常分为室类场景、室外场景两种情况。
室内场景的特点是摄相机被包围在一个个房间内(不光第一人称游戏很多第三人称游戏的室内场景也可以看做这样的情况),房间于房间之间通过门窗来连通。在一个房间里面的只有视线能穿过打开的门或窗才可以看到其他房间里面的场景物体。在这种情况下诞生了一种算法叫做门裁剪。
门裁剪就是将室内场景看成由一个个封闭区域组成的,封闭区域与封闭区域之间通过门连通。如果摄相机在一个封闭区域(房间)内,首先根据摄象机的视锥体裁减掉不在视锥体范围内的所有物体。然后用同摄相机所在封闭区域相连的门来裁减摄象机的视锥体排除掉该门相连的封闭区域内所有不同门裁减后视锥体相交的物体。然后继续用裁减后的视锥体和新探测到的与门相连区域的门来继续裁减视锥体直到没有新的裁减视锥体产生。这样经过裁剪后必然只有未被裁减的物体对屏幕图象有贡献。而被遮挡的物体和视觉区域外的物体都被裁减掉了,这大大的加快了室内场景的绘制。
室外场景其实也可以分为两大类,一类是城市场景一类是野外场景。城市场景就是一些有很多房屋的场景,可以通过房屋的门窗看到房屋内部,并且没有太大的地形起伏和植被。这样的场景同室内场景的处理方法没有太大的区别。可以将城市想象成一个大的房间,而这样的大房间通过房屋的门窗同一些小房间相连接。本质方法还是采用门裁减,只是相对于室内场景而言,房间是一个个凸壳而城市场景本质上是一写非凸的壳包裹的。
野外场景通常有很多植被,地形的起伏变化很大,基本上没有太多的遮挡发生,视觉区域也比较的广阔。所以野外场景的绘制更多的是依靠质量有损的场景简化算法。常用的是LOD(层次细节简化),所谓LOD就是说对于场景中需要精细的部分用更多的面片来表示而不需要精细的部分用少量面片来近似。这可以剔除大量的场景面片。
野外场景的算法有地形算法和植被算法、水面算法、大气算法等等。
地形算法的目的是要简化地形的显示。主要基于两种原因一是绘制地形需要大量的面片,大量面片的渲染要占用大量的处理时间,一是对于地表的特性不同需要大量的不同的贴图,而贴图要占用大量的存储空间。所以需要两类方法来简化。
一类简化地形渲染的面片数量,通常地形面片的简化根据其对屏幕图象质量的贡献可以如下划分,同摄相机距离远的地形面片投影到屏幕上占用的像素区域小只需要少量的面片来表示。另外地形起伏小的区域,由于本身就没有精细的变化可以用少量的面片来表示。这就产生了地形的LOD算法。通常地形的LOD算法有:二叉三角形树、地形几何贴图、ROAM、块LOD算法。
一类简化地形的贴图,由于地形面片的数量巨大,而覆盖的区域广,其贴图数量非常惊人,所以导致地形贴图的空间复杂程度高。简化地形贴图就是要用少量贴图来表现地形的地貌特点。通常的方法是为每个地形面片赋予一个索引到地形贴图的序号,大量的地形面片重复使用少量的地形贴图,为保证地形贴图的连续性过度,不同贴图面片相连的区域用纹理混合的方式把采样到的不同的贴图数据进行加权平均。为保证地形贴图的随机性,可以采用生成贴图的办法通过几个参数、几个原始贴图和随机数来产生贴图应用于不同的地形面片。
地形植被的绘制同样面临面片数量巨大的难题,想象一下绘制草地,一个草地上有那么多的草,即使每个草用少量的面片来表示也需要天文数字般的面片来表现,这在实时渲染里面是不可能完成的任务。通常绘制草将运用一种类似于绘制毛发的算法。就是在草地的地形面片的每个边上生长出一个矩形面片(两个三角形面片),然后将草的贴图贴在该面片上,同时在地形面片上空分层覆盖几个面片,然后在面片上贴上草的分层截面贴图。这可以让绘制草成为可能。另一方面草地的渲染也遵循LOD的规则,就是对于远处的草地只用覆盖在地形面片上的一个贴图来表现,而近处的草地才用从地形面片的边上垂直生长出面片并贴上贴图和在地形面片上覆盖多层草的分层截面贴图的形式来表现。
除了绘制草外,绘制树也是一个难题,绘制树不能应用绘制草的方法,因为树的体积比较大,同时树叶的数量也非常的巨大,而且从各个方向观察有不同的视觉效果。绘制树需要运用告示牌的技术,告示牌就是一个面片上贴上一个贴图。目前有一些运用告示牌的技术来表现树的方法,一种方法就是直接在一个与人视线垂直的告示牌上渲染树的贴图,这种方法是最节省但最不精细的算法,通常当人的视线同地面的法线夹角很小的时候会看到树被放倒了,一种叫正交IBR方法,就是产生一组以树为中心的平面族,每个平面上绘制树在该平面方向上投影的贴图。这种方法对于距离视点距离比较远的树能够很好的表现但是当视点很近的时候,会感觉到明显的失真,树像几张相互垂直的纸。但是其需要的面片数量很少只要几个面片就可以表现一棵树。另外一种算法是著名的Speed Tree算法就是树的枝条用真实的面片网格来构建而枝条上附着的很多片树叶用始终与人视线垂直的告示牌上渲染树叶群的贴图来表现。这种方法可以很逼真的表现树,即使视角垂直地面或者距离很近的情况下所表现的树也非常真实,缺点是当视线方向频繁变动的时候会感觉到树叶的频繁变动和失真。最高质量的算法就是完整的用三角形面片来表现树和树叶,但无疑这是非常消耗时间的。由于这些算法的优缺点SI Engine将采用多种方法来表现树,选择算法的依据是距离的远近和树本身的复杂程度。如果树不复杂那么对于距离非常近的树木,如视点在树冠下将采用树的完全三角形绘制方法也就是不简化,然后距离远一点如距离视点有几米的距离那么采用Speed Tree算法,再远一点那么用LOD算法简化树干的面片数量,距离在中等远的程度如500米外采用正交方法,如果距离非常远一公里外那么采用一个告示排来表现树。如果树本身非常复杂那么即使在树冠下面那么也采用Speed Tree算法。
水面同地形一样他是起伏的,并且他有随时间变化的特点。但是他的起伏变化比地面变化平滑,没有尖锐的棱角(巨浪除外)。同时水面是透明的他有反射和折射的特点。绘制水面的起伏通常只需要变化他的法线方向,让他反射和折射的景物发生变化就可以产生很好的结果。所以SI Engine绘制水面采用如下的方法,一是对于一般的起伏平缓的水面可以直接用过程性的法线贴图和函数生成的法线贴图在绘制用一个平面表示的水面的着色过程中用变化的法线去扰动反射贴图和折射贴图就可以了。对于瀑布,巨浪等等的水面则需要针对性的构造多层的面片网格并用地形算法来根据距离远近简化面片表示,并在绘制过程中运用过程性贴图和反射折射环境贴图来渲染。还有就是水面排击岸边的效果可以用两层水面和他们不同的过程贴图来表现。
野外的大气效果如天空,阳光和雨,云彩,可以通过构造一个天空包围球并在上面进行过程性贴图来实现,由于不出现场景简化可以归类于一般物体的渲染。
为了同室内处理部分的数据结构同构和处理室内和室外过度的情形,野外数据也被划分到一个封闭区域中。他通过通向室内的门同室内场景相连。对于通过门看到的室内场景同样使用门裁减方法。
以上所说的只是根据场景特点采用的渲染简化算法。游戏中面对的场景并不仅仅只有以上所说的这些,还有很多的场景物体,他们相互遮挡,利用他们的遮挡关系还可以剔除掉一些场景物体。
SI Engine将利用八叉树来管理一个区域内的场景物体,通过八叉空间划分树来帮助场景裁减以提高裁减算法的效率。同时将采用硬件支持的闭合测试来剔除大部分被遮挡的场景物体。硬件支持的闭合测试就是:用物体层次包围球和包围盒来代替物体,进行尝试性渲染,如果尝试性渲染过程中没有影响Z缓存的数据就说明物体是被已经绘制的物体所遮挡的可以剔除掉。否则就绘制物体本身。通过八叉树的空间排序性我们可以按距离视点远近和物体大小,先绘制近处的大物体,然后在绘制后续物体前先用物体的包围盒进行上述的遮挡测试,如果测试通过就绘制物体否则就忽略掉物体的绘制。由于包围盒的面片数量比较少,所以能够很大的剔除掉被遮挡物体的绘制,而增加的测试代价可以忽略不计。
同时场景数据的表示方法对于显卡处理时间和显存的消耗是不同的,比如一个三角形网格其中有很多共用的三角型顶点,那么这些共用的顶点如果用三角形条带和索引表来表示就只需要一个顶点数据和一个索引来表现,但是如果将网格分割为一系列三角型的列表来表示则会出现很多重复的顶点索引,而如果不用索引方式来表示顶点,那么就会额外的出现很多重复的顶点数据。所以加快图形渲染的另一种方法就是进行几何压缩,把三角形网格中的三角形尽量的分配到少树的几个三角形条带中。并用索引来表示三角形的顶点的数据在三角形顶点表中什么位置。这个简化过程不出现在实时调用的场景管理中而是在场景编辑器生成关卡文件前完成,SI Engine的场景管理实际上只管理已经经过预处理和几何压缩后的三角形数据。
终上所诉,SI引擎采用下面的场景管理结构:
备注:SI Engine不特定使用一种地形算法,因为地形算法的实用领域各有不同,ROAM算法表现的地形较为连续能保证地形质量,但是频繁调用ROAM会失去高效性,所以对于中小地形场景比较适合ROAM算法。而块LOD虽然地形的跳变比较明显,但是比ROAM快速适合大型地形场景,可以使用于军事防真和3DGIS等等图形应用。为了不失去游戏引擎的通用性,SI Engine设计多种算法的地形类,根据设计者用途和设计特点在制作平台中指定地形的采用那种算法,地形的算法类别信息传递到虚拟机中有虚拟机建立特定地形对象来进行地形场景管理。SI Engine具体实现ROAM地形类、块LOD地形类、地形几何MIP贴图地形类。具体算法可以写几本书了故这里不着描述。
2) 资源管理系统:
所谓资源管理就是要在系统需要时候合理的分配计算机系统中的硬件资源如内存、显存等,处理系统对资源的争用,以及在不需要时候合理的释放硬件资源.而SI Engine游戏虚拟机的资源管理主要是要处理好场景元素的顶点缓冲区、图元缓冲区、纹理缓冲区在内存和显存中的分配。将频繁使用的缓冲区分配到显存上,将不频繁使用的缓冲区分配到内存上,在减少显卡设备总线的数据传输的同时,保证系统高效和稳定的运行。
SI Engine针对游戏系统的特点以及结合Direct9c API对缓冲区管理的规定,将在场景元素对象上绑定场景元素需要使用到的缓冲区指针。而所有的缓冲区实行基于优先级的集中管理。最初系统为场景图元的每个元素的缓冲区设定一个初始的优先级别,在绘制一帧时,绘图需要使用某个缓冲区的时候,将增加缓冲区优先级的读数,相反如果在绘制一帧时缓冲区没有被使用到将降低缓冲区优先级的读数。当缓冲区优先级的读数增长到一定数值时,并且缓冲区的大小小于规定数值时候,将按照优先级排序,选择优先级靠前的缓冲区并根据缓冲区大小和显存地占用量把缓冲区直接分配到显存上。被分配到显存中的缓冲区如果在绘制一帧时候没有被使用到,那么将直接将缓冲区优先级降低很大一个数值,并迁移到内存中。长期没有使用的分配到内存的缓冲区将被操作系统按自己的方式兑换到硬盘的分页文件中。
SI Engine设计了一个资源管理对象来管理所有的资源,资源对象里面保留了所有的缓冲区对象指针。在设备重启、设备丢失、缺页、缓冲区分配失败等等事件发生时候,自动的更新缓冲区的分配和处理设备异常。
3) 渲染管理系统:
我们知道要将场景图元送入显示硬件并调用Direct9c接口进行绘制需要首先设定设备的状态参数然后调用绘制函数进行图元绘制。设备状态参数包括设定变换矩阵、渲染目标缓冲区、深度和模版缓冲区、纹理、VS/PS程序等以及他们的协同控制参数和设备工作参数等等。而图元绘制是在这些状态参数的系统控制下,将顶点、图元、纹理像素等送入设备按规定的设备设置和如下图所示的顺序进行处理。
所有设备状态参数和场景数据构成一个完全指导单步渲染过程的渲染作业。通常一个场景由很多的场景图元和绘图资源构成,而一个场景图元由很多不同的组成部分构成,每个独立的部分对应不同的绘图资源,通常不能够在有限的设备状态和设备存储中设定一个图元的所有绘图资源(比如目前设备的极限是在单步的绘图中设定小于8个的纹理贴图),并且一些渲染算法要求按顺序的多次设定互斥的设备参数来绘制场景图元的一个组成部分(如绘制透明体需要先设定透明度测试让设备过滤所有的透明面片来首先绘制所有不透明面片,然后设定透明度测试过滤所有不透明面片,并设定颜色混合来绘制所有不透明面片。由于需要在两个不同的设备状态集上对同一组面片数据工作两次所以必须分两步完成)。这就使场景的绘制过程通常不是一个单步的渲染作业,而是一个按顺序进行处理的渲染作业的工作队列构成的一个渲染工作集。场景的渲染过程可抽象的表示为:
由于很多情况下后续作业需要前面的作业提供一些产品数据添加到绘图资源里才能让后续作业正确的完成,所以场景渲染工作集中的作业的前后相继顺序通常不能够任意的改变。必须按规定的顺序来完成,如果作业的处理顺序被改变通常会让场景的显示失真和出现错误的结果。
在图形系统里,从单个图元的角度来审视绘制过程可以发现,对于一个图元的绘制,我们需要指定图元显示需要实现那些特效(有什么形式的阴影,是否折射和反射等等)。而每一种特效需要让设备按顺序做那些渲染作业。通常实现同样的特效对于不同的场景图元在作业中设备状态的设置和作业的顺序上并没有不同,只是针对不同的绘图资源而已,实现一种特效的工作集中共同的作业顺序和作业中设备状态参数的设置就构成了固定的特效的渲染算法。对单个图元而言我们只要告诉了它要使用那几种特效算法,和每种算法的作业要用到他那些绘图资源,它应该就知道了如何去表现自己的全部信息。
但是从整个场景绘制的角度来看则不然。从单个图元的每一个特效的算法中我们可以抽取出一个工作集这个工作集能够正确的绘制一个图元的一个效果。但是正如画一幅水彩画我们先画树还是先画树下的人,先用红色画还是先用黑色画将得到不同的图象一样,多个图元的绘制顺序和不同特效的绘制顺序将导致绘图系统得到不同的图象。所以在绘制整个场景的过程中必须将从绘制单个图元的工作集中的作业拉出来进行正确的排序和组合才能构成绘制场景的正确的工作集。另外由于频繁的设置设备参数和装卸绘图资源更加的耗费设备的处理时间,所以对于能得到同样绘图结果的两个不同组合的工作集其效率也是不同的。
如何实现不同渲染算法的工作集的优化组合在保证正确渲染出场景的情况下能够让渲染得帧速率最优就是渲染管理的目标.优化渲染得效率的方法只有一种有效的途径就是没有前后相互关系的渲染作业按资源聚合。以减少资源到显示处理设备的频繁调度。
在SI Engine中渲染管理按如下的方式实现:系统实现渲染器类.由渲染器类来集中管理渲染工作集或实现某种渲染算法的单步渲染作业。并保存渲染算法中和不同渲染算法间的渲染作业的前后相继逻辑。从这一点看这有别于其他的游戏引擎。其他的游戏引擎通常渲染的过程是固定的,它抽取出有限的几种特效的渲染算法,并将他们排列成一固定的工作过程。按固定的路线来渲染场景特效。而SI Engine的渲染体系结构在支持固定的渲染算法的情况下还允许添加自定义的渲染算法,以及允许优化渲染过程以提供灵活性和高效性。
渲染器基类的体系结构如图:
一个渲染器对象包括了一个渲染作业或一个渲染工作集的全部信息。在渲染器类的框架下,我们就可以实现智能的渲染作业排序和调度了。我们实现渲染排序基于以下的逻辑。
首先如果根渲染器类别是人自定义了渲染作业顺序的渲染器,那么该渲染器中子渲染器的顺序不能改变,也就是处理人自定义固定的渲染过程的情况,不需要实现渲染器排序了。
如果不是人自定义的固定渲染器那么如果A渲染器的产品是B渲染器的资源,那么A必须先于B处理也就是A必须排在B前。这是最上层的逻辑。
然后如果A渲染器的产品和B渲染器的产品存在重合,也就是AB渲染器影响相同的目标表面或资源那么AB渲染器的顺序按渲染器对象中的前置渲染器类别规定的先后顺序进行排序。
在做了前两种渲染器排序后,对渲染器中的资源表进行归并。使资源表中不出现重复的资源。
然后对于以上排序中没有决定先后次序的渲染器按资源进行排序。也就是如果A和B没有渲染逻辑上的前后关系、A渲染器的有资源a、b、c而B渲染器有资源a、d、c、那么将A渲染器的资源排列成b、a、c资源B排成a、c、b并让处理A渲染器后直接处理渲染器B可以看到由于处理的资源在相邻渲染器中排列顺序邻近所以在A渲染器工作后B渲染器不再需要调入a、c资源可以大大的节省资源调度的时间。资源排序就按照这种逻辑进行。
作完资源排序后还可以按照把连资源也没有前后相继关系的渲染器按照状态参数设置表进行聚类。也就是状态参数设置相近的的渲染器集中到一起。这样可以节省渲染状态设置的时间和频度。(其实资源排序和状态参数设置排序都是节约处理时间的手段,只是考虑游戏场景的资源通常都是少数的几种在不同渲染器中重复现象比较多而资源调度更加消耗时间所以将资源排序放在渲染状态参数排序前通常能够更加有效的节约时间)
SI Engine的是一个可扩展渲染算法的引擎,在制作平台中将设计专用的自定义渲染器编辑器来添加特定渲染算法的渲染器和渲染器集合。自定义的渲染器随工程文件中脚本传递给虚拟机,以添加虚拟机的渲染特效。同时由于设备的支持能力不一样,有些高端设备能够支持质量很高的渲染特效,而低端设备只能支持质量较低的渲染特效。所以在制作平台中会为场景物体指定几个不同的渲染特效配置,场景物体对象信息中有一个包括若干个渲染配置对象的列表,每个渲染配置对象指定一组设备能力要求信息和一组渲染器列表构成的渲染工作集合。这些信息传递给虚拟机后,虚拟机检测设备配置根据设备能力选择设备能够支持的的渲染配置,并从这些渲染配置的渲染器集合中获取渲染工作集。而具体选择哪个渲染配置来渲染场景物体,取决于游戏玩家的配置文件。通常用引擎开发出的游戏出厂时候指定最低配置作为玩家的默认配置以保证游戏能够顺利的执行。游戏配置文件记录了几种相似的特效算法的描述(也就是游戏设计者给场景物体的一组渲染器指定的类别名称)如果让一个场景物体选择时优先应该采用的一个。游戏虚拟机加载关卡文件和渲染配置文件因为设备能力不支持失败后,恢复上一次的默认设置,并按默认设置加载。
SI Engine的制作平台除了能够编辑自定义的渲染器外,还允许利用渲染流程编辑器进行渲染流程的自定义,渲染流程编辑器允许编辑生成的或新建立的渲染工作集。改变渲染工作集合中作业的处理顺序或者在渲染工作集中添加或删除渲染作业的渲染器。指定那些设备能力配置下使用那种渲染流程。渲染流程编辑器修改后的渲染工作集被作为最终的渲染工作集传递给虚拟机用于管理渲染的过程。
注意:从渲染器的结构我们可以知道渲染器可以包括顺序的子渲染器件,也就是说,最终的渲染工作集可以被一个根渲染器通过多层的树状结构来体现,而渲染的顺序是在根渲染器表现渲染树中采取先根遍历的方式得到的顺序。
SI Engine 默认渲染流程采用如下的渲染器树实现(有些渲染器由于处理器速度限制在游戏设计中默认被参数屏蔽掉,可以根据需要打开,图中兰色包围的部分被默认屏蔽掉,直接将其下层渲染器按顺序挂接到其上层渲染器,并且如果下层指向相同的渲染器时候,相同的将不被重复处理)
4) 动画播放系统:
3D游戏引擎中动画播放的实质实际上是在在特定时刻改变场景物体变换矩阵、改变VS/PS中参数以及改变纹理和材质实现的。
具体可划分为:场景图元动画、摄像机动画、纹理材质动画。
纹理和材质动画是按时间改变一个场景物体面片上纹理和材质实现的。如过程性纹理、视频纹理和时变纹理。对于纹理材质动画我们可以给场景物体赋予多列纹理和材质队列或建立一个视频纹理,在开启某个动画时指定某个文理材质队列为活动的队列,探测时间事件,并在时刻到来时候移动活动纹理材质队列中的当前指针,让指针所指向的纹理和材质作为当前纹理材质或根据具体时刻在当前纹理材质和队列中下一个纹理材质间混合。具体方法取决于渲染器的设计。
摄像机动画是在移动摄像机的情况下对场景的投影矩阵和视区变换矩阵进行改变引起的动画。通常交互式改变摄像机的时候就会发生该动画,这时候不需要进行额外的处理,只要保证摄像机类的参数同这些矩阵同步就行了。如果在某个时刻需要由系统根据具体路线而不是玩家控制来时变的改变摄像机位置方向,这个时候让摄像机处理时间事件,并根据时间来设置其参数就可以实现这种情况下的动画。
场景图元动画是场景图元的位置和方向的改变引起的动画。通常分为:变形动画、骨骼动画、变换动画、替换动画。
变形动画是场景物体的顶点按固定的轨迹变化位置和法线方向产生的。这种动画要求场景物体记录顶点的多个位置和法线方向,在动画开始后顶点的位置和法线方向根据时刻在两个相邻位置数据和法线数据间插值得到。这可以通过特定的VS程序实现。
变换动画是按时间改变场景物体的变化矩阵实现。可以为场景物体的指定一组(物体只有一种动作)或多组世界(物体有多种动画)矩阵。在开启某个动画的时候指定一组矩阵活动,并根据时间事件在活动的一组矩阵中的两个相邻矩阵中插值来决定当前时刻的世界矩阵,通过这种方式实现动画。
骨骼动画是变换动画的一种进化形式。实现骨骼动画的场景物体由皮肤和骨骼组成。皮肤就是面片网格,而骨骼对应于面片顶点的世界变换矩阵。一个顶点可以有多个世界矩形,顶点的位置由多个世界矩阵变换出的多个顶点位置来根据各个矩阵影响顶点位置的权重来插值得到。这种动画的好处是对于动物等等由皮肤和关节构成的物体,关节转动时候,由于关节两边的皮肤由于位置不同需要用两个矩阵来分别变换,但是如果用传统变换动画的话关节处的皮肤会出现断裂。为了防止断裂,关节处皮肤的顶点应该根据两个矩阵变换出的位置插值得到。SI Engine设计一个骨骼动画场景物体对象来表示存在骨骼动画的场景物体,该对象存储一个面片表和多个变换矩阵,以及面片上顶点在各个矩阵中的权重。用特定渲染器的VS根据矩阵和权重来渲染场景物体。在动画发生是后,骨骼动画对象的一个或多个世界变换矩阵随着时间事件发生改变。渲染出的物体就产生了动画。
替换动画要求场景物体对象存储一个对象的不同网格表示,在动画发生后,随时间事件渲染不同的网格来显示场景物体,就实现了替换动画。由于这种动画相邻变化的差异比较大,为了动画的连续性,可以在渲染两个不同表示之间插入一些中间帧,中间帧采用两个表示的渲染结果进行颜色混合得到。就可以提高这种动画的连续性。
5) 调试和基准测试系统:
基准测试系统利用Direct9c的功能,允许程序获取或输出当前的显示帧速率、设备处理的每一阶段的数据吞吐率、每一阶段的设备处理延迟、算法的处理时间、硬件的支持能力、显存和内存的占用率等等数据。用于寻找到系统瓶颈以便修改场景图元的属性和改变渲染的算法。调试系统则允许用一组控制台命令来在图形渲染得每一个环节插入断点,跟踪设备事件。以及察看系统数据的变化和设备状态等。
G. 物理运算:
SI Engine的物理运算主要是为场景物体对象规定对应的虚拟物理对象,并在虚拟物理对象中管理场景物体的物理力学属性如:位置矢量,受力矢量、动能矢量、动量矢量等等。并设计虚拟的力场物理对象如:重力场对象、阻力场对象等等。所有的虚拟物体对象都抽象为质点。根据力学计算虚拟物理对象物理属性。同时设计一系列的探测器对象来检测虚拟物理对象的物理属性改变,并引发物理事件调用该事件的处理脚本来处理(物理事件的处理脚本是用户设计游戏时候加入的,通常可以根据改变的物理属性来设置场景物体的位置)。同时物理运算部分还设计碰撞检测器对象来探测场景物体的碰撞并发送碰撞事件,调用场景物体碰撞处理脚本。碰撞检测器对象利用场景管理中的八叉树来进行碰撞检测,这可以节约大量的检测处理时间。
H. 音频播放:
SI Engine的音频部分主要是利用Direct Sound的API来实现音频的解码和播放。音频播放主要是要作到:波形数据缓冲区的分配和管理、音频事件的处理、音响的特效。在三维场景中的音频问题不单是简单的播放音乐和音频,还应该考虑到声音的空间效应,也就是说音效受发声源的空间位置,音响的传播方向,音响的传播距离,音响的音响范围等属性影响。并且音响还有多普勒、衰减等效应。Direct Sound提供了这些效应的API。
SI Engine的音频部分将音频分成了几种形式:
1) 无空间属性的波形音频:这种音频用普通音频类产生的对象来管理,普通音频类负责加载一组音频波形数据,并分配音频缓冲区以及在播放函数被调用时候播放音频数据。音频数据通常存在于文件流中,加载数据不能够一次性的加载流中的全部数据,而是只预加载一部分,在播放开始后一边播放一边从流中加载音频数据。多个音频对象可以共用一个流,所以普通音频对象要保留其在流中的起止位置。
2) 无空间属性的背景音乐:这种音频用普通音乐对象来管理,音乐音频区别于波形音频的是他是记录的乐曲是音符的组合,多数用的是MIDI格式,系统用波表设备或软波表来播放音乐。同样普通音乐对象,需要管理音频缓冲区,需要在播放时候预读音乐数据。
3) 无空间属性的音乐和波形音频同步复合音频:这种音频就是像歌曲一样既有用音符表现的音乐又有语音的波形数据,并且还必须在两种数据间同步。用一般音乐音频同步对象来管理。一般音频音乐同步对象分配波形音频缓冲区、音乐缓冲区和同步点表,处理音频和音乐间的同步播放和流的同步读取。
4) 空间音频(由于Direct Sound的功能限制不支持空间的音乐,所以空间的音乐也利用软波表中的音符波形数据将音乐也转化为波形音频处理):这种音频数据用空间音频对象管理,空间音频对象除了实现普通波形音频的播放外,还指定音频的位置,方向,范围,衰减系数等等空间属性,利用Direct Sound的空间音频功能实现播放。同时由于音频的空间属性,需要在摄像机位置改变后裁减空间音频对象,在开始对象的音频播放时候只播放空间音频影响范围包含摄像机位置的音频数据。
5) 文语转换音频(Text To Speech):文语转换是通过MS的TTS引擎,将输入的文字转换为语音。这可以提供给游戏设计者用于实现游戏对白,但这种方式比直接的音频节约存储。SI Engine通过一个TTS类封装了MS的TTS引擎调用。甚至SI Engine的TTS类提供了一个发音到嘴形输出的API可以用于驱动玩家对话动画.
I. 视频播放:
SI Engine的游戏虚拟机是工作在三维图形模式下的,所以视频的播放表面是在场景三角形面片的纹理表面上。SI Engine不设计视频解码部分的函数,而是直接利用DirectShow的功能根据视频文件属性来自动组装的Filter Graph来解码视频文件流。只是Filter Graph的Render Filter是一个将解码后的图象数据渲染到纹理表面的Filter.所以设计视频纹理类来管理视频播放。当视频播放开始后,没有被场景资源管理挂起视频纹理类随时间消息将视频文件流中的数据解码到纹理对象的表面上。如果视频纹理是场景可见区域外的某个物体上的纹理,那么由于该场景物体长期被裁减掉,其资源的优先级别比较低所以有很大的可能性纹理资源会被挂起这个时候视频纹理类就不会调用视频解码功能空耗处理时间了。但是由于SI Engine为保证游戏的连续性,它的资源管理并不确保不在场景可见区域外的纹理都是被挂起的,所以游戏视频虽然在场景可见区域外但是同场景可见区域接近,时不时因为摄像机位置的改变会被场景使用,这个时候存在着不在场景内的视频纹理同样被解码到纹理表面的情况。这种情况在考虑游戏连续性的情况下无可避免。视频纹理类不单可以用于场景物体表面贴图还可以用于GUI系统中的特定视频控件中以用于游戏片头视频的播放。
为保证游戏中玩家间即时视频通信的实现,SI Engine提供一对控件。一个控件利用DirectShow功能将绑定到摄像头的图象采集Filter作为源Filter,压缩视频到MPEG4网络传输格式的Filter作为视频变换Filter一个将数据发送到点到点目的通信端的Filter作为Render Filter以实现玩家视频的采集和发送。另一个控件将接受网络视频数据的Filter作为源Filter,网络MPEG4流解码Filter作为变换Filter而渲染到纹理的Filter作为目的Filter,并将渲染到纹理Filter的目标纹理绘制到一个2D GUI控件上。实现玩家即时通信视频的接收控件。这一对控件供游戏设计者选用制作游戏中的视频通信。
J. 人工智能:
由于游戏的人工智能非常复杂和多样,SI Engine不可能设计出支持所有类型的游戏的人工智能制作器件,人工智能对于游戏开发者而言还是需要在脚本中去定义,但为了节约开发人工智能的复杂度,SI Engine的人工智能部分为游戏开发者提供人工智能的一些常用函数、类和接口的API,供开发者编辑事件处理脚本的时候调用。
人工智能部分设计如下的几种人工智能API:
反应式推理API:是由用户根据SI Engine的产生式脚本的书写规则,定义用字符串表示的产生式列表,输入到反应式推理类里面,在给定条件列表时候利用该推理类检测是否有规定结果的推论产生。
状态机API:包括确定性状态机和非确定性状态机,用户可以利用制作平台的状态机产生器,通过绘图自动生成状态机类的脚本。用于在用户自定义的事件处理脚本中调用。用户调用状态机类,需要用户向状态机对象输入一组状态机能识别的条件字符串用于驱动状态机改变,状态机输出当前的状态。
感知器和BP神经网络API:用户可以在通过在制作平台的神经网络定义器里面绘制神经网络和接点初试权值,并用一组输入向量到一组输出向量来训练该神经网。并生成神经网络类的脚本,用户在事件处理脚本中可以调用神经网络对象通过输入一组参数向量来获得结果向量。并根据结果向量来通过逻辑判断来执行一些行为,用户脚本可根据行为的结果来测量是否被误判断,并推测该输入向量实际应该有什么输出向量,然后将该推测输入到原始神经网络来持续训练该神经网络对象。以支持游戏智能的自适应学习。
模糊推理API:同反应式一样的处理过程,知识推理过程利用模糊逻辑。而规则用模糊逻辑的形式书写。
A*寻路算法API:这是游戏中最常用的人工智能,A*寻路算法类保留一份图象作为路径判断的依据,最优通路表现为图象上的黑色区域,而障碍表现为图象上的白色区域,而黑色到白色间的灰度表示的区域的颜色代表不采用该路径的权值,白色就是绝对不采用的路径点,黑色就是尽量采用的路径点,该图象上每一个2D点同3D空间中的3D坐标有一定的对应规则。该规则由用户自己的脚本定义。A*寻路算法类,只是用于输入一个源2D点和一个目标2D点。A*类输出一个2D点序列表示来源点到目标点的建议路径,该建议路径尽量的用A*算法来满足路径上每个点的权值的和最小。
K. 网络通信:
SI Engine为满足网络游戏的需求,提供了一套自己的网络通信基础结构。
分析网络游戏的通信需求,可以发现游戏对于网络通信的要求是:高速、低延迟、大客户量。对于通信的安全性,游戏并没有特表高的要求,但是存在有一些网络游戏出于对游戏公平性考虑和保护玩家权益要求网络游戏平台能够提供对玩家关键性隐私数据的安全性保护(反盗用)和防止不合理的客户端对服务器的数据欺骗(反外挂)但是这很难就通用引擎中设计出来只能够在具体游戏中利用脚本具体设计。对于游戏通信的稳定性要求也不太高,不需要保证每个客户通信稳定,只需要单个或有限的客户端的断线和错误不影响到所有的玩家,并能够保证出错的客互端能从新登陆加入游戏。同时网络游戏的通信量比较大,需要较大的服务带宽。同时一个游戏引擎的网络通信部分,如果要设计,必然应该设计成同具体游戏类别无关的。
SI Engine的网络通信实现如下的功能:
客户端管理:负责玩家的客户端登陆,登陆服务器的客户端,服务器记录其IP地址和路由信息,用玩家用户名来标识。所有服务器到该客户端的信息发送或其他客户向该客户的信息发送都通过用户名来表示目的地址。而客户登陆的具体IP地址对用户透明。
网络数据对象同步和访问:负责服务器维护的网络对象和客户端的网络对象代理的数据同步和客户端对网络对象的数据更新发布和客户端对网络对象的函数接口调用。SI Engine中的所有数据对象的类都派生于网络对象类,并且网络对象类如果属性指明是需要服务器进行数据同步的,那么服务器将保证每个客户端看到的该网络对象的数据是相同的。这是SI Engine实现游戏网络通信的主要形式。通过网络对象的数据同步,任何客户在游戏中对远程对象的数据修改都能够反映给其他客户,从而实现了游戏的网络交互。同时由于客户端访问网络对象实际上是直接从网络对象的本地代理对象上获取属性数据和调用成员函数,所以网络对象对开发者而言实际上是透明的,他可以在脚本中像操纵本地对象一样的去操作网络对象,不必要关心数据同步的机制和具体网络协议,减小了网络游戏开发的难度,开发者甚至根本不需要去编写一行网络代码就可以实现一个网络游戏,只是在制作平台中将一些数据对象指定为需要同步就行了。这个机制可以通过.NET Remoting技术很好的实现。
资源下载更新:在用SI Engine设计的游戏中,资源管理在关卡准备阶段加载资源,如果发现资源不存在于本地,那么就向连接的服务器下栽该资源。资源下栽的过程是通过P2P方式来进行的,以节约服务器贷款。SI Engine在资源管理类里面实现了该网络机制。把服务器上游戏的资源文件夹和本地的资源文件夹通过资源管理的API透明的合并成一个虚拟的文件系统,就象一些原代码管理机制一样,如果游戏在本地的资源文件同服务器上同名资源文件不一致就自动启动资源同步机制保持客户端游戏用到的资源文件是服务器上最新的资源文件。这利于实现网络游戏的媒体化经营,可以让服务器通过修改和增加资源的形式来扩展网络游戏的场景和关卡。并且资源的下载过程对设计者而言还是透明的。并且P2P方式的资源下载节约了对服务器带宽的占用。
信息收发和传递:SI Engine提供服务器与客户之间,以及客户与客户之间的消息收发API,用于开发者在脚本中定义自己的网络通信。同Socket不同的是这些API封装了服务器和客户具体的网络地址。用用户名和服务器名来表示手法的来源和目的地址。消息收发有两种形式一种是连接(基于TCP),一种是非连接的(基于UDP).
客户间即时通信:SI Engine提供客户间的即时通信控件(包括文字、图片、视频、语音通信),来设计游戏中的玩家交流平台。
数据库访问服务:SI Engine提供给为保证通信的高效率,SI Engine的网络服务基于集群服务和负载平衡的思想来设计。在服务器端,服务可以分为:
门户登陆服务:门户登陆服务,是客户端登陆游戏服务器统一入口,因为玩家不可能知道所有的节点服务的拓扑和地址信息,只能通过登陆一个统一地址的门户服务来进入游戏,而门户服务在登陆过程中负责记录登陆客户的用户名和从节点数据库检索服务中获取用户的信息。并通过负载平衡机制,和根据玩家所在的当前关卡信息,分配不繁忙的关卡服务器来负责管理客户在当前关卡的远程对象数据同步和远程对象接口调用请求。分配了节点服务后,玩家客户端同服务器的通信转向分配的节点关卡远程对象同步服务。门户登陆服务还维护登陆客户和所有节点服务的地址信息,用于客户间和客户到服务器间的消息传送。
节点服务分配服务:负责节点服务的建立和分配。所有的具体服务器设备都必须安装节点服务分配服务。以便于门户服务在这些服务器设备上建立某种节点服务。
节点关卡远程对象数据同步服务:节点关卡远程对象数据同步负责一个关卡的网络对象的数据同步,保证登陆到该关卡的客户的客户端访问网络数据对象的数据时候访问到同样的数据。并执行客户请求的网络对象的成员函数。不光如此,由于网络游戏的玩家的大规模性,对于一个关卡用一个节点服务来维护数据同步有时候是不效率的,因为有些关卡的玩家数量很大,所以同一个关卡也可以通过分配多个节点服务器来服务,只是关卡维护的网络数据对象和玩家连接,根据玩家更新和访问网络对象数据的频繁程度被分割到不同的节点服务器上,每个节点服务器维护不同的网络数据对象和玩家连接,通过节点服务器间的数据同步来保证同一个关卡的网络数据对象在不同节点服务器上同步。当然这不是最优的做法,因为多个同一关卡的节点服务器间的通信也需要耗费大量的内部带宽和处理时间。保证服务效能的有效做法是,游戏设计者,尽量的分割网络游戏的关卡,并规定每个关卡的最大进入人数。这样SI Engine的数据同步服务的自动机制就能够很好的保证数据同步。另外节点关卡远程对象数据同步服务所维护的网络对象有两种形式:一种是GET形式的,也就是客户端访问该对象数据的时候,通过网络对象代理从网络上获取网络对象数据。另一种是PUT形式的,也就是玩家从本地的网络对象镜像上获取数据,不通过网络。但是玩家修改网络对象数据的时候通过网络通信修改服务器上的网络对象数据并将该对象数据的修改传送给所有保留了该数据对象副本镜像的客户端,让这些客户端修改该网络对象在本地的镜像对象数据。这两种形式的网络对象的数据同步对带宽的占用情况是不同的,GET模式适合于频繁修改数据但不常读数据的对象。而PUT模式适合于频繁读数据而不常改数据的对象。在游戏设计中使用制作平台用布局场景或对象属性修改或脚本建立网络对象时候游戏设计师需要根据实际情况和经验设置这两种同步模式。
节点资源下载服务:负责客户端向服务器下载资源的网络通信。通常在客户端发出资源下载请求时候,门户服务器根据客户端的资源请求表分配一组接点资源下载服务给客户端。每个节点服务负责资源文件的一部分的下载。节点资源服务可以存在于其他在线玩家的客户端机器上用于从该玩家客户机上下载该玩家拥有的资源文件,以减少服务器端带宽。
节点数据库检索服务:游戏服务器的数据库主要是用于存储玩家保存的信息。玩家保存的信息由于没有太大的相关性可以分布式储到不同的数据库服务器上,以加快访问数据库的速度。SI Engine为开发者提供访问和培植节点数据库服务的API,节点数据库连接的数据库类型取决于开发者通过这些API对节点数据库服务的设置脚本。
以上的服务是指软件服务,并不要求一定要安装到不同的服务器上,可以多个服务安装到一台服务器上。对于开发单机游戏的情况,你可以把所有的服务都安装到客户端上。
(3)游戏制作平台体系结构
SI Engine游戏制作平台负责生成关卡文件,并初试化游戏关卡的资源。主要有以下组成部分:
界面编辑器
场景编辑器
场景布局
包围盒生成
包围球生成
包围网面生成
环境贴图盒编辑
PRT球编辑
辐射度光照贴图生成
二步光线跟踪光照贴图生成
PRT预计算
环境贴图生成
门和区域编辑
区域八叉划分
几何压缩
纹理编辑器
纹理编辑
纹理坐标编辑
材质编辑
凹凸编辑器件
法线贴图生成
水平线贴图生成
LOD编辑器
离散LOD定义
连续LOD生成
地形编辑器
地形编辑
水面编辑
草和毛发编辑器
植物编辑器
粒子特效编辑器
动画编辑器
骨骼动画编辑:
变形动画编辑:
替换动画编辑
渲染器编辑器
渲染流程编辑器
状态机编辑器
BP神经网编辑器
活动响应编辑器
对象编辑器
脚本编辑器
游戏测试器
具体功能所明如下:
A. 界面编辑:
通过提供一个界面编辑器来可视化的交互布局2D的界面控件和容纳场景的视口控件。实现对控件的建立、拖动、属性编辑、事件脚本编程等功能。
可以将定义的界面保存为界面定义脚本文件。并指定特定的界面文件为关卡的初始界面,从初始界面跳转到其他界面需要通过脚本编程来卸载旧界面和加载新的界面文件。界面上的一些控件如对话框可以初始化为隐藏状态,在特定的事件处理脚本中用脚本程序显现。
B. 场景编辑器
场景布局:
通过提供一个场景布局器,来建立场景物体、命名场景物体,为场景图元对象加载网格和贴图等资源、修改场景物体的属性、设置场景图元对象渲染特效。
通过拣选物体并移动,旋转、放缩来改变场景物体布局。
为多个场景物体的建立组,或将某个场景物体指定为其他场景物体的子物体,其位置和方向被表示为相对于上层物体相对位置和相对方向。
场景物体不单指场景图元对象还包括各种光源、摄相机,卷积雾,卷积光,阴影体,虚拟物体,地形,水面,植物,草和毛发,粒子对象,环境贴图盒,PRT盒等等。并且在场景编辑中都可以交互式的改变他们的位置和方向以及属性数据。
同时还可以设置整个场景雾化效果等等。
场景布局可以在多个不同方向和投影方式的视图中进行。并可以改变编辑视口的摄影方向和投影方式。
可以改变移动、旋转、放缩的参考坐标系。
并且硬件不能直接绘制的参数曲面表示的场景图元一样可以被场景布局装入和布局。只是传递到虚拟机后参数曲面被虚拟机关卡装入过程三角形条带化。
场景布局还定义场景物体的事件激发条件和编辑场景事件的处理脚本。
物理编辑:
建立和设置场景物体的虚拟物理对象并同场景物体绑定。
建立和布局虚拟的物理力场对象,并应用于场景物体。
建立虚拟的物力参数探测器以及碰撞检测探测器,设置场景关卡的物理探测的触发条件如时钟,其他事件触发等等。
为物理事件添加处理脚本。
包围盒生成:
自动生成指定场景物体的包围盒,用于门裁减、闭合探测和碰撞检测等。
包围球生成:
自动生成指定场景物体的包围球,用于门裁减、闭合探测和碰撞检测等。
包围网面生成:
自动按设定的误差范围,生成指定场景物体的包围网面,包围网面用于裁减和测试的效率不高,但是可以用于代替原始图元网面来生成卷集模版阴影,可以提高模版阴影的渲染效率。
环境贴图盒编辑:
通过交互方式编辑添加环境贴图盒。并指定环境贴图盒是否伴随某个场景物体移动,以及指定环境贴图盒子的摄相范围。以及指定那些场景对象的环境贴图通过该环境贴图盒子得到。
PRT球编辑:
通过交互方式建立PRT球,并为PRT球指定一个环境贴图或贴图为环境光源贴图。并指定那些静态场景对象绑定到该PRT球,以便计算他们的传递系数,在渲染中他们的漫反射将受该PRT球影响。
辐射度光照贴图生成:
为需要辐射度光照图的场景对象,计算他们的辐射度关照贴图,并保存为他们的纹理。
注意辐射度光照贴图和PRT都是作用于物体漫反射,他们不能同时被一个场景图元对象使用。
二步光线跟踪贴图生成:
从一个指定摄像机位置通过二步光线跟踪算法渲染出一个贴图,保存为纹理文件,供其他图元添加贴图时候使用。
PRT预计算:
计算所有PRT球环境光照系数,并计算PRT球绑定的物体的光能传递系数。
环境贴图生成:
计算所有静态的环境贴图。并保存为纹理文件和加载到需要该贴图的场景物体资源中。
门和区域编辑:
通过交互式编辑指定一个虚拟网面范围内的场景图元或选中的场景图元构成一个区域。
用交互式编辑绘制一个虚拟多边形作为从一个区域到另一个区域的门。
区域八叉划分:
为每个区域执行八叉树划分,并建立八叉树来管理区域内物体。
指定物体的卷积模版阴影的产生多边形网格:
可以指定有卷积模版阴影的图元的卷积模版阴影的产生多边形网格是用包围盒、包围球、包围多边形面还是原始图元多边形面本身。
几何压缩:
调用几何压缩算法,压缩场景物体的几何数据。几何压缩算法主要有三角形条带化、顶点数据表示精度有损压缩、以及几何数据有损拓扑编码和预测编码。几何压缩能够减少资源文件的大小,但是在三角形条带化后的几何压缩步骤产生的数据硬件都不能直接支持,所以几何压缩后的数据传递给虚拟机后将在关卡初始化阶段被一定程度的解压缩成硬件能够支持的条带化几何数据,以变虚拟机渲染时候不需要进行复杂的解码运算,以加快渲染速度。。
变换动画编辑:
在场景编辑器中建立命名变换动画对象,并定义其关键时刻。指定每一个关键时刻,场景中运动物体的位置和方向。
C. 纹理材质编辑器:
纹理编辑:
进行纹理的装入,命名,卸载。纹理可以是视频表示的过程纹理。
纹理坐标编辑:
主要针对一个场景物体,调整纹理坐标。
如果场景物体没有纹理坐标,那么可以用投影盒或投影球,投影圆柱等方式建立投影纹理坐标,或进行通过建立和自动生成顶点纹理地图的方式来建立纹理坐标。并用交互编辑的形式通过调整这些投影坐标体的位置和方向或顶点在纹理地图上的坐标来编辑这些纹理坐标。
如果场景物体有对应该纹理的纹理坐标那么可以通过顶点纹理坐标数据修改的形式来调整纹理坐标。
材质编辑:
建立命名材质,为该材质设置参数和设置纹理槽的纹理。材质包括动画材质,动画材质用关键时刻和材质对列表的形式保存动画开始后每个时刻的材质。中间材质插值得到。
D. 凹凸编辑器:
法线贴图生成
装入场景物体几何数据的高精度和低精度版本,参考高精度版本计算低精度版本的法线纹理贴图。法线贴图可以通过法线贴图渲染器的Vetex Shader和Pixel Shader程序进行逐像素的渲染,以变用低精度模型就能很好的近似高进度模型的表面细节。
水平线贴图生成
装入场景物体几何数据的高精度和低精度版本,根据高精度版本计算照射到物体表面像素的光线不被本身凹图遮挡的角度范围。并以此为依据生成低分辨率物体的水平线贴图。水平线贴图能用于渲染物体本身凹产生的阴影。
虚拟位移贴图生成
装入场景物体几何数据的高精度和低精度版本,根据高精度版本计算低精度物体的虚拟位移贴图。
E. LOD编辑器
离散LOD定义
将物体模型的精度分成几个LOD级别,为每一个级别装入该级别进度的物体的多边形表示,并生成离散LOD场景对象。并设置图元在什么情况下使用那一级别的多边形表示。
连续LOD生成
利用几何缩减算法为指定的场景物体模型生成连续LOD对象。并设定在那些距摄像机距离的情况下使用多少顶点的多边形表示。
F. 地形编辑器
地形编辑
装入或随机产生或绘制地形高度图象。指定高度单位和地形网格数量和地形的范围和地形场景简化算法,生成原始的地形网面。并交互式的在地形网面上调整。和覆盖地形贴图。并生成地形场景对象。和保存为地形文件。
水面编辑
利用水面的地形高度图,指定算法和参数用生成地形的相同方式生成和调整水面。并对突变的水面落差随机的生成瀑布面片,并指定水面的法线过程贴图或水面的法线变化Shader函数。自动的按设定的参数为环境包围盒基准边长生成很多覆盖水面的相连的环境包围盒集合。最后生成水面场景对象。还可以通过两副或多副不同时刻的水面高度图来生成变动的水面。这种变动的水面能根据两副相邻时刻的水面地形高度图快速突变的地方生成浪花。
G. 草和毛发编辑器
为指定的场景物体,通过三角形边沿法线生长出矩形面片和源多边形根据参数设置多次沿法线位移复制出分层覆盖面片并在这些面片上覆盖静态贴图或过程贴图的形式来生成毛发和草。并设置其显现的摄像机距离范围。最后形成草和毛发对象,可以被保存或作用于场景物体。
H. 植物编辑器
装入植物的原始枝干网面、叶子网面、叶子贴图。并自动生成植物的全多边形表示、SpeedTree表示,正交IBR表示、单个布告牌表示。并设置这些表示到不同LOD级别,设置LOD级别的距离条件。生成植物对象。
I. 粒子特效编辑器:
设置粒子发生器的类别,粒子速度,范围,方向等参数生成粒子特效场景对象。
J. 动画编辑器件:
骨骼动画编辑:
装如或建立骨骼物体,建立骨骼物体需要装如一个多边形作为皮肤,并建立一系列骨骼,设置骨骼对皮肤上顶点的影响权值。
并建立一系列的命名动画。选择每一个命名动画,为其添加和设置关键时刻,并编辑该动画在关键时刻的骨骼位置。最后生成骨骼动画场景对象并保存骨骼动画资源文件。
变形动画编辑:
装入网格物体,并建立一系列的命名动画,为每个命名动画添加关键时刻,并在关键时刻设置网格物体顶点的位置和法线更改的目标位置。生成变形动画对象。保存到资源文件。
替换动画编辑:
建立一个替换动画物体,并建立他的一系列的命名动画,为每个命名动画添加关键时刻,并在关键时刻装入特定的多边形表示。生成替换动画对象。保存到资源文件。
K. 渲染器编辑器
通过可视化的组织渲染器层次和编辑渲染器属性及渲染器脚本编辑,引用的效果文件及其CG代码编辑来自定义渲染器类。
L. 渲染流程编辑器
通过可视化的组合渲染器树以及为渲染器树上的每个渲染器设置属性参数和指定资源来定义渲染流程。
M. 状态机编辑器
通过可视化的绘制状态机及设置状态迁移的输入条件来在脚本中生成状态机类。
N. BP神经网编辑器
通过可视化的绘制神经网络节点和连接权值,并用输入输出向量进行训练来生成神经网络类脚本。
O. 活动响应编辑器
通过绘制活动响应状态机并设置活动检测的条件和时机,以及为活动状态迁移事件编辑处理脚本或录制场景变化宏的形式来定义活动响应事件检测和行为响应方式。
P. 对象编辑器:
维护和编辑关卡里面的对象树,对象树以树状结构管理所有的内存对象,在SI Engine中所有的类(包括场景物体类、界面控件类、物理对象类等等)实例化成对象后都被命名和加载到对象树。对象树管理的对象能够被脚本检索。同时可以通过可视化的编辑选择对象树上的对象,来修改对象的数据属性和为对象的事件接口添加处理脚本。
Q. 脚本编辑器:
提供一个文本编辑界面,用于编译和编辑修改脚本程序。脚本程序包括关卡启动初始化启动函数、用户自定义类程序、特定对象或类的事件处理程序、关卡结束解析程序、制作平台生成的类程序(如渲染器类、渲染流程类、状态机类等等)、用户自定义的渲染函数、调试用控制脚本命令。SI Engine脚本使用C#语言编写,并利用.Net的运行时编译和反射功能编译和执行。
R. 游戏测试器:
定义一些测试指标,并实际调用虚拟机运行游戏关卡,并获取测试数据。可进行中断和调试。以及通过控制台执行一些调试用控制脚本。