浅析游戏引擎的资源管理机制——扒一扒Unity3D中隐藏在背后的资源管理

  游戏中一般有大量资源,如网格、材质、纹理、动画、着色器程序和音乐等,游戏引擎做为作游戏的工具,天然要提供良好的资源管理,让游戏开发者用最简单的方式使用资源。游戏引擎的资源管理包括两大部分:离线资源管理和运行时资源管理。本文仅对前者进行简要介绍,并结合Unity3D和OGRE进行分析。git

资源创做与导出算法

  游戏中的资源由各类数字内容创做工具(DCC, digital content creation)进行创做,如:数据库

  • 三维模型:3ds Max,Maya等;
  • 纹理:Photoshop等;
  • 音乐:Sound Forge等;
  • ………………

  DCC每每支持多种导出格式,如:编辑器

  • 3ds Max:3DS、AI、DDF、DEM、DWG、DXF™、HTR、FBX、IAM、IGES、IPT、LP、LS、MTL、OBJ等;
  • Photoshop:PSD、TIFF、EPS、PCX、GIF、JPEG、PNG、PICT、TGA等;
  • ………………

  游戏引擎通常会支持指定DDC的部分导出格式,例如Unity3D支持3ds Max导出的FBX格式;或者针对特定资源创做工具编写导出插件,例如OGRE有多种三维建模软件的导出插件虽然基本上全部DCC都支持多种导出格式,可是不少状况下这些格式都不适合游戏引擎,由于工具

  • 导出的内容过于复杂,游戏中只用到其部分数据,而游戏每每对性能的要求比较苛刻,因此须要去除冗余数据;
  • 许多DCC导出的格式读取比较慢,并且还有一些是封闭格式致使引擎没法读取。

  所以,在DCC导出资源后,须要引擎进一步处理,将资源转换为引擎的内部格式,这种处理被称做Asset Conditioning Pipeling。使用Unity3D的童鞋应该会发现,每次导入资源的时候都要读条,就是在进行Asset Conditioning Pipeling;OGRE在这方面的支持不够完善,这部分工做由自定义的导出插件完成。性能

资源的“编译”与“连接”优化

  因为导出的资源存在一些问题,须要进行必定的转换,这个转换被称做Asset Conditioning Pipeling,包括2个步骤:动画

  • 资源“编译”

  读取单个资源的数据,将其转换为游戏中能够直接使用的格式(使用效率最高或较高的格式),例如从新对Mesh的顶点进行排序,或使用BC5等压缩算法对纹理进行压缩。这个过程与C语言的编译有些相似,所以取名为“编译”。固然,若是导出的资源能够直接使用,那么能够跳过这一步。spa

  • 资源“连接”

  在游戏中,许多资源并非单独使用的,例如三维模型,它引用的材质和纹理是单独存在的资源。在上一步中,引擎对单个资源进行“编译”,将其转换为能够直接在游戏中使用的格式;这个步骤将全部的资源进行“连接”,使得游戏在运行时能够找到每一个资源所依赖的全部资源,例如三维模型能够正确的找到其须要的材质和纹理。这个过程与C语言的连接有些相似,所以取名为“连接”。固然,若是导出的资源能够直接使用,那么也能够跳过这一步。插件

  

  Unity3D对这部分提供了比较完善的支持,所以只须要导出引擎所支持的标准资源,并放入Assets文件夹,引擎会对其进行“编译”和“连接”,结果就在Library文件夹中(里面乱七八糟的,虽然咱们看不懂,可是Unity3D很喜欢);OGRE没有提供专门的Asset Conditioning Pipeling工具,所以全部操做都在资源的导出插件中完成,没有进行单独的“编译”和“连接”。

资源管理数据库

  在资源经过Asset Conditioning Pipeline以前,引擎须要存储处理该资源的方式,通常使用metadata(元数据)来描述,例如指定某个纹理应该是以何种方式压缩。引擎经过资源数据库来管理metadata,资源数据库既能够简单的使用XML文件进行描述,也可使用MySQL等数据库。游戏开发者经过引擎提供的接口实现资源的从新配置,例如在Unity3D编辑器中能够修改Mesh的压缩方式,选择是否优化Mesh等。

  游戏引擎的资源数据库通常要提供以下功能:

  • 建立和删除资源;
  • 查看和修改现有资源;
  • 将资源移动到其余路径;
  • 支持资源的相互引用,而且在被引用资源移动路径后,保证引用有效;
  • 提供多种便捷的查找资源的方式。

  使用Unity3D的童鞋能够发现,Unity3D提供了比较完善的资源管理的功能,使用起来比较轻松。

资源读取(运行时)

  在开发过程当中,全部原始资源以单个文件形式进行保存,以方便修改,可是在游戏运行读取资源的时候,为了加快读取速度,通常会将资源打包成一个或多个文件。打包的缘由很简单,从硬盘中读取文件的时间中,主要由三部分组成:

  1. 硬盘寻道时间;
  2. 打开文件的时间;
  3. 读取文件的时间。

  最后一项是不可能改变了,除非使用速度更快的存储介质;可是将多个文件打包成一个文件,能够缩短前面两项的时间。Unity3D在发布游戏的时候,会将资源进行打包;OGRE没有自定义打包资源的方式,通常打包为一个或多个ZIP文件,或不打包资源

实例分析

Unity3D

  拷贝Unity3D工程的时候,必定要拷贝“Assets”、“Library”和“ProjectSettings”文件夹。资源都在“Assets”,设置都在“ProjectSettings”,“Library”是来打酱油的?非也!若是不拷贝“Library”,打开工程之后你必定会大吃一惊,以前的设置全没了?!并且场景文件里的东西也是乱成一团!结合上文,则很容易理解这种诡异的现象,明白为何少不了这个“打酱油”的“Library”。

  将资源放入“Assets”文件夹,切回Unity3D,则进入Importing Assets状态(进行Asset Conditioning Pipelining),以下图

导入资源

  在这个步骤中,Unity3D针对全部的资源生成metadata,并进行“编译”、“连接”,转换为游戏能够直接使用的资源。转换前的资源保存在“Assets”中,转换后的资源保存在“Library”中,全部的资源在Inspector面板中能够修改metadata的数据,以下图

“Library”文件夹

Inspector

  若是使用SVN等版本控制器,须要同步全部资源及其metadata。打开Edit->Project Settings->Editor,将Mode修改成“Meta Files”(默认“Disabled”),以下图

选择“Meta Files”

  Mode修改成“Meta Files”后,回到资源文件夹,会发现每一个资源都多了***.meta文件,以下图,而这些.meta文件保存了这些资源将如何被Asset Conditioning Pipeline处理。

带metadata的资源文件

  如今Assets文件夹中不只有全部的资源,并且还有对应的metadata,“Library”完全打酱油了,此时在拷贝工程或使用SVN同步工程时才能够忽略“Library”文件夹。

  在发布的游戏中,资源文件以下图所示。能够发现,Unity3D对资源进行了打包,以减小资源载入时间。

发布后的游戏资源

  总的来讲,从导入资源,生成metadata,“编译”、“连接”资源,再到发布游戏时打包资源,Unity3D都封装好了,以最简单的方式提供给咱们使用,极大的提升了游戏开发者的工做效率。虽然可能第一次在用的时候只是感受Unity3D用的比较简单,但它确实在背后作了不少工做,只是咱们没注意而已。

OGRE

  OGRE在这方面的支持与Unity3D相比差距比较大,只提供了资源的导出插件;发布的游戏中,可使用ZIP对游戏资源进行打包,未提供自定义资源打包方式。固然,整体来讲,它是一个至关不错的图形引擎,最重要的一点是,它是开源的。

相关文章
相关标签/搜索