前提:美术很随意得使用贴图、材质,大量的材质虽然名称不一样,可是实际上材质属性是相同的。node
因而,在导出时,在依次处理材质时,应该将新的材质属性与已经收集到的材质进行对比,若是是相同的,则使用已存在的材质。工具
同时,虽然mesh中的submesh实际上是根据MatID来做划分,可是通常状况下,mesh中的submesh的vertex decl一般是彻底相同的。性能
那么其实能够将全部相同的vertex decl的submesh合并在同一个geometry(VB)中,submesh使用不一样的index buffer来绘制,减小绘制时的VB切换。优化
因而,就有了shared geometry的共用,若是submesh的vertex decl与之不一样(例如ABC是diffuseMap,DE是diffuseMap + specularMap,FGH是diffuseMap + specularMap + normalMap),则本身使用独立的geometry来绘制。插件
另外,还要对于mesh中全部的submesh所使用的material进行排序,以减小没必要要的state切换。orm
并且还有一个好处是,material的数量、mesh的大小都会减小,意味着减小了磁盘IO和文件解析所须要的时间。排序
接下来,就是本文的重点出现了。ip
问题总有2个:it
1. 想象中优化后的场景目录的文件数量和大小,都应该会相应减小。但实际中发现,的确大多数模型数据都减小了十几K到几十K不等,可是少数模型的mesh尺寸变大了。效率
这个现象很奇怪,为了分析缘由,我使用了工具对二者进行了二进制对比。
有意思的是,变大的文件,例如以前的十六进制数据为: AB CD EF GH,变大的数据变成AB CD 00 00 EF GH 00 00。
经验告诉我,确定是某些原先使用16bits描述的数值,如今变成32bits了。
相信朋友们已经猜到了缘由,即合并submesh以前,每个geometry大小都是65535之内,因而16bits IB就够了
合并以后,vertex数量超过了65535,因而个人导出插件自动切换为32bits IB来描述了
经过搜索资料,了解到10年前的GPU对于32bits IB的处理,除了带宽上略有影响以外,并不会有额外的性能惩罚
而随之优化带来的batch减小以及VB等state切换所带来的FPS提高,个人结论是这样的优化是值得的
进一步的优化思考是,我目前是使用的triangle list保存的IB,即一个face使用3个index;若是改成triangle trip,那么IB是颇有可能控制在65535以内的
2. 美术不必定会将同一个物体的多个子物体合并(Attach),例如手机:显示屏幕、外壳、电池、天线,是分开为多个mesh存在,而后合成一个group。
这样子并不会影响实际使用中的操做,由于毕竟scene中仍是有一个叫“手机”的node。
可是理论上,咱们仍是但愿这几个物体合并在一块儿,甚至想到说,既然上述的material和geometry的优化,那为何不把整个场景都在导出时自动merge到一块儿呢?
而后我想固然得写了一个maxscript,在导出以前会自动将场景中全部的mesh合并在一块儿。
可是实际状况是,虽然感受上应该会更流畅,单个scene在观察时也会有些许提高,可是当画面是由多个scene分块构成时,camera frustum的cull就废掉了。
哪怕只有scene A的一棵小草被看到,整个scene都会被绘制出来,反而会影响到渲染效率。
优化无止境,同窗需努力。