一些总结,如有不对之处还请指正
小型物体
- 静态物体尽量合并图集,使用同一个材质。注意,大批量的小型物体静态批处理的时候会造成内存的浪费
- 动态物体也应该合并图集,使用同一种材质,严格控制顶点数量(因为动态批处理顶点上限是900)
可以使用遮挡剔除对小型物体进行优化,小型物体不建议使用LODGroup,应使用层距离剔除进行处理
中大型物体
使用视椎体剔除和遮挡剔除进行优化,同时配合LODGroup。另外从遮挡剔除的角度来说,物体被分割成小块有利于增加遮挡剔除的效率。
模型
软边: 指相邻的三角面共享同一个顶点,它的法线以及所有和顶点相关的性质(切线、顶点色)和UV都共享
硬边: 指相邻面具有不同的顶点,对同一个位置顶点的切割意味着更多的数据、内存以及提交到GPU的数据
所以能用软边表达的尽量不用硬边。
对于模型来说,顶点位置、法线以及一套UV是必须有的,切线等则不是必须要有的。
unity中切线是一个vector4,如果有个1024个顶点的模型,就可以省下16kb的内存;
另外,删除或者合并在视觉上过小的面;同时避免过大的面,可以通过插入必要的线进行分割,这个分割操作考虑光照和面剔除的因素。
地形
unity的地形系统提供了一套基于距离的内置LOD控制系统
地形LOD的控制有3个方面:
- 地形自身的网格、网格细分密度
参数 | 说明 |
---|---|
drawHeightmap | 直接关闭,不渲染地形 |
heightmapPixelError | 这是网格的细节,调大这个值可以渲染出一个低分辨率的地形网格(1-200),默认是5 |
heightmapMaximumLOD | 调整网格密度,值越大,网格越粗糙 |
BasemapDistance | 默认是1000,大于这个值会使用一个低分辨率的高度图来生成网格 |
上面这些参数的功能在表现效果上有重复,或者说内部实现途径不一样。
- 地形的渲染复杂度、阴影、材质和光照
参数 | 说明 |
---|---|
CastShadows | 打开/关闭地形的阴影 |
Material | 材质的LOD机制 |
光照 | 主要是光照探针,和实时GI有关 |
- 地形上的修饰物(树木和草)
参数 | 说明 |
---|---|
drawTreesAndFoliage | 显示/关闭修饰物、植被 |
detailObjectDensity | 草的密度,这是一个乘数 |
detailObjectDistance | 根据距离剔除草 |
treeBillboardDistance | 根据距离用面片代替树木 |
treeCrossFadeLength | 上面操作距离的淡入参数 |
treeDistance | 根据距离剔除树木 |
对于大地形的优化,可以考虑分块,有个第三方插件t4m,这样可以动态加载和卸载地形块。
对于小地形,通过LOD调整就行。
UI
- UI的绘制调用(Drawcall)
每个独立的画布和图集都会打断UI元素的批处理;在UI上使用自定义材质也会打断批处理;两个UI元素中间插入异类也会打断批处理。 - 图集的划分
尽量确保一个情境下(一个功能或者一个面板)的UI使用一个图集,即使偶尔有几个精灵在多个UI上出现,如果不是很大,应该使用冗余的方式保持图集独立。同时尽量规划通用的UI精灵。 - 文字
尽量不要使用Text组件的Best Fit特性,这会在字体文件中存放大小各异的字形;静态Font文件可以只包含那些已经使用的字符; - UI和完美像素
在screenoverlay模式下会强制UI元素的边界和像素对齐,这会产生额外的cpu计算。 - 物理
UI如果有遮盖现象,应该只保留其中的一个Raycast Target属性,不然每个都会响应。如果没有交互需求,则应该关闭。
物理引擎
实现物理碰撞时要做好层划分,设置好FixedUpdate的频率、平衡物理引擎的性能。
顶点数量
参考值是每一帧渲染的物体,当前视口的顶点总数不超过100万,通常而言保持在10000-20000最佳,这对于绝大多数Android设备很友好。实际开发中,建议采用LOD GROUP和遮挡剔除等技术来减少顶点数。对于移动平台来说单个角色模型超过3000已经很多了。
贴图
对于贴图,尽量是2的幂次方,因为计算和存储最终都要以2的幂次方为单位。对于移动平台建议以1024为标杆,最大不要超过2048。对于摄像机距离会有变化的3D游戏,一定要打开mipmaps(虽然内存多了三分之一)。
ETC、DXT和PVRTC都是硬件压缩,如果硬件不支持,那么贴图加载时由CPU来解压缩,建议使用unity默认的压缩方式,它会针对平台适配。ETC是Android普遍支持的一种压缩格式,但是不支持alpha通道,因此贴图含有alpha通道时,unity默认在贴图大小、质量以及渲染速度之间选择了相对平衡的格式RGBA-16bit,不过对于硬件Tegra,应该使用DXT5。如果是ios则使用PVRTC的压缩格式。
其他
- 慎用后期处理,如果一定要用,使用小一点的渲染纹理,尽可能减少片元着色器的计算量;如果可能,把最终效果所需要的计算尽量集中到一个pass中完成。
- 慎用透明效果,如果一定要用,尽可能的将多个透明图层进行合并,因为透明灰带来重绘问题;对于透明物体尽可能剔除正面/背面,减少渲染像素数量;如果可能,使用混合来实现透明效果,同时尽量避免透明物体叠加,因为每个透明物体的渲染都会迫使GPU对于每个像素执行一次片元着色器。
- 对于美术人员提交的粒子特效着重关注