记一次 glTF 模型的绘制性能提升:从ppt到dove,丝滑感受


测试不易,机会难寻。转载请带连接:https://www.cnblogs.com/onsummer/p/13543826.html;全网@秋意正寒

转换思路

同样一个模型,分别取如下转换思路:

  • 原始模型??fbx??gltf
  • 原始模型??obj??gltf

但是我在打开中间格式fbx和obj时,发现这两者虽然顶点数量一致,三角形数量一致,但是使用 Windows 3D 查看器查看时,发现前者的绘图调用次数高达1600多次,而后者的绘图调用次数只有217次,效果是完全相同的。
遂打开gltf文件进行分析,对比gltf数据对象如下:

对比gltf对象 fbx obj
node数量 1600多+2500多 1
mesh数量 1600多 1
primitive总量(每个mesh的primitive数量和) 1600多 217
特点 1个mesh存1个primitive,有2500多个node用于记录层级关系 用1个node包裹1个mesh,mesh下有217个primitive

所以,故推断影响 gltf、3dtiles(b3dm格式)渲染性能的一个重要指标,就是 primitive 的数量,primitive 是 GL 库绘制图形的最小单元。

在上表中看到有2500多虚node其实是不直接引用 mesh 的,所以即使 node 的总数有 3700 多个,但是实际上只复现了 1600 多次 mesh,且由于 1个 mesh 只有 1个 primitive,所以绘制次数等于1600多次很正常。

要性能还是要逻辑?

这是一个很难取舍的话题,如果需要在 gltf 层面组织好属性数据、数据逻辑分层,那么要尽可能控制好 node 的树状结构,控制好负责引用mesh的node的数量,控制好 primitive 的总数,尽量把材质一样的 primitive 合并。

而如果要追求极致的性能,就不用太在意 node、mesh的组织,只要遇到材质一样的 primitive,合并就是,遇到相对坐标不一样,上转换矩阵算它。

空间换时间

三维渲染是一个极其昔时的话题,因为现在似乎磁盘容量是足够的——什么你跟我说文件大了下载慢?你搞辣么大的模型干啥?有大模型不会分拆吗吗吗吗

所以,很多时候要用空间换时间。

gltf 允许 1个mesh 由多个node 引用,那么这个 mesh 的绘制次数就会累加,虽然复用了mesh下辖的 primitive所指向的数据,不用存储多份mesh可以达到“只存一份数据重复绘制多次”的效果,但是这对性能毫无卵用,因为总的 primitive 数量还是上去了。

这个时候可以把需要重复的顶点根据 node 的坐标转换信息计算出来,重复塞到尽量少的primitive中去。

有人说你这样顶点数量上去了,文件体积也上去了:朋友,普通的750ti亮机卡绘制100w个点没什么压力的~,文件体积这个,就需要数据转换者自己权衡到底是重复mesh的引用,还是把重复的图形多存一份(位置不一样)塞到 primitive 中了。