引擎开发随笔之资源导入

102 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

曾在十多年前看到一个大佬说,游戏引擎的核心就是资源管理。确实,游戏引擎必须要能管理好各种资源,而且不论是运行时资源还是项目工作流中的资源。今天来聊一聊资源导入,这个经常被忽略的一个引擎功能。

以前我们用自研引擎做游戏几乎都会用到自定义的一些资源格式,比如模型文件格式什么的。这种自定义格式的好处是匹配自己的需求,可以根据需求优化,这是通用格式无法做到的。这种自定义资源,一般会开发专用的转换工具,将通用格式的资源转换成自定义格式的资源,并且保存在项目中。

除此之外,游戏还需要对一些资源进行某种处理,比如图片如果需求二次幂,可能会在载入时判断,如果不是二次幂,就用程序补全。再比如预乘alpha,一种做法也是在载入图片后,如果需要预乘,就进行一次预乘操作。这种载入后的预处理操作是会消耗载入时间的,当然好处是游戏引擎直接支持通用格式的图片,然后还能兼容二次幂和预乘alpha。这种做法对于工作流来说比较轻量化,比较适合轻量级的引擎。

当你的游戏项目或者自研引擎复杂起来之后,需要支持各种各样的自定义格式,以及需要做越来越多的预处理之后,为了方便管理以及优化掉预处理的时间消耗,就需要建立一个资源导入功能。可以直接观察的例子就是Unity引擎的Import Setting。Unity会对各种资源进行预处理,并且有各种选项可以设置,因此每个资源都会有各自的导入选项,Unity会在资源第一次导入或者变化时,根据导入选项对资源进行操作,并且将结果保存在缓存中。因此Unity会有Library目录。

Unity有资源导入是顺理成章的,因为它是基于编辑器的引擎。资源首先是通过编辑器导入。如果我们没有编辑器,或者暂时还没有,那么我们怎么办呢?就比如我目前缓慢推进的mini3d.js项目,这个算不上引擎的实验性框架,虽然很弱小,但是也有资源预处理的需求。比如目前mini3d.js只支持obj格式的模型文件,但是在载入obj后会判断模型文件中是否有法线和切线数据,如果没有,且又需要,就会自动生成法线和切线。现在这么做确实是权宜之计,因为没有资源导入这个一次性的处理过程,就只能在载入后处理了。当然编辑器肯定没那么容易就有,但是也还是可以通过工具链加一个转换过程,比如提供一个命令行脚本对资源目录中的资源进行扫描,处理后存在一个res_build目录中,引擎直接使用res_build目录中的处理后的资源。但是我们还是需要提供导入选项的设置和保存,没有编辑器的话,就只能给每个资源提供一个手工编写的资源定义文件了,如果有这个文件就会进行处理。看,是不是也可以凑合用,但是确实很不方便,所以还是需要一个编辑器,哪怕仅仅是一个资源管理编辑器也行。用这个编辑器打开一个项目,会列出目前所有的资源,每个资源可以编辑它的导入选项,然后提供一个资源编译的按钮,也可以打开编辑器时自动刷新。感觉有了这个东西之后引擎瞬间就有点高大上了,然后以此为基础在继续开发场景编辑等等功能。

好了,本文并不是预告mini3d.js要开发一个编辑器,每个引擎的定位并不一样。有那么一种需求就是简单导入一下引擎文件,通过调用API就可以直接搞事情,资源最好也直接使用通用格式。载入速度么?小项目忽略不计了。。你说用你的引擎我还得先建一个项目,学习一下各种设置,在git上保存各种meta文件还不能弄乱了,引擎升级编辑器我还得先升级一下所有资源,如果有问题还得手工解决。。有这时间我事情已经搞完了