资源类型与导入
- 外部导入资源
- 模型网格Mesh
- 纹理
- 音乐音效
- 字体
- 动画
- 视频
- 内部创建资源
- Prefab
- Animation Controller
- Timeline
- RenderTexture
- ParticleSystem
- VFX
- 内部创建资源也需要考虑不同平台设置以及第三方package导入
资源设置检查
- Unity UPR 工具:https://upr.unity.cn
- Asset Checker
- UPR后台看资源检测报告,报告会给出一系列优化建议,后面篇章会解读这些建议的作用
Audio导入优化
- 根据平台选择合理的音频设置,原始音频资源尽量采用未压缩WAV格式
- 双通道音频如果左右声道一致,建议开启Force To Mono选项来节省内存(会变成单声道)
- 移动平台对音乐音效统一采用单通道设置(Force to Mono),并将音乐采样频率设置为22050Hz(经验值)
- 移动平台大多数声音尽量采用Vorbis压缩设置,IOS平台或不打算循环的声音可以选择MP3格式,对于简短、常用的音效,可以采用解码速度快的ADPCM格式(PCM为未压缩格式)
- 音频片段加载类型(Load Type,影响引擎编辑器中的大小)说明
- 简短音效导入后小于200kb,采用Decompress on Load模式
- 对于复杂音效,大小大于200kb,长度超过5秒的音效采用Compressed In Memory模式
- 对于长度较长的音效或背景音乐则采用Streaming模式,虽然会有CPU额外开销,但节省内存并且加载不卡顿
- 当实现静音功能时,不要简单的将音量设置为0,应销毁音频(AudioSource)组件,将音频从内存中卸载。
Model导入设置检查与优化
模型导入流程:
- DCC中优化原始导入模型文件,删除不需要的数据
- 统一单位
- 导出的网格必须是多边形拓扑网格,不能是贝塞尔曲线、样条曲线、NURBS、NURMS、细分曲面等
- 烘培Deformers(变形器),在导出之前,确保变形体被烘培到网格模型上,如骨骼形变烘培到蒙皮权重上
- 不建议模型使用到的纹理随模型导出
- 如果你需要导入blend shape normals,必须要指定光滑组smooth groups
- DCC导出面板设置, 不建议携带场景信息导出,如不建议导出摄像机、灯光、材质等信息,因为这些的信息与Unity内默认都不同。除非你自己为某DCC做过自定义导出插件。
- 原始模型文件对性能的影响点
- 最小化面数,尽量不要靠面数增加细节;不要使用微三角形(一个三角面只包含个位数的像素);三角面分布尽量均匀
- 合理的网络拓扑和平滑组,闭合模型(非闭合模型会引起烘焙错误,还会增加顶点和边数)
- 尽量少的使用材质个数
- 尽可能少的使用蒙皮网格,同一模型尽量使用相同的蒙皮网格,特殊需求除外
- 尽可能少的骨骼数量
- FK与IK节点没分离(Unity不支持导入的IK骨骼),IK节点没删除
模型导入设置中的一些选项
- Scene中关于Import的选项,一般没有特殊需求可以不开启
- Meshes网格设置
- Mesh Compression,会节省磁盘空间,但不会节省内存空间,适合激进的情况,需要观察开启后是否正常运行,开启此选项要尽可能使模型制作规范,最好是闭包模型
- Read/White,开启后会增加一个副本,一份在内存一份在显存,只有需要运行时修改模型才建议开启,skinmesh也需要开启(否则动画会出问题)
- Optimize Mesh和Generate Colliders一般保持默认,除非要禁止优化或者需要网格级别碰撞
- Geometry设置
- Index Format :如果确认网格顶点数不超过65535,可以使用十六位索引
- Normal、Tangents相关设置:印象中与法线光滑有关,如果要模型描边可以用。不需要法线、切线时可以关闭
- 光照第二套uv生成:如果不需要光照烘焙可以关闭
- Player中设置
- Vertex Compression: 是否启用模型顶点中的诸如法线/切线/UV等信息的压缩
- Optimize Mesh Data: 删除没有使用的模型顶点信息,如法线/切线/UV等
纹理导入设置优化
纹理的基础概念
纹理类型
- Default:默认的纹理类型格式
- Normal map:法线贴图,可将颜色通道转换为适合实时法线贴图格式
- Editor GUI and Legacy GUI:在编辑器GUI控件上使用纹理请选择此类型
- Sprite(2D and UI):在2D游戏中使用的精灵(Sprite)或UGUI使用的纹理请选择此类型
- Cursor:鼠标光标自定义纹理类型
- Cookie:用于光照Cookie剪影类型的纹理
- Lightmap:光照贴图类型的纹理,编码格式取决于不同的平台
- Single Channel:如果原始图片文件只有一个通道,请选择此类型
纹理大小
现代显卡一般要求纹理长宽为2的幂次方,unity默认会将其转为最小2的幂次方大小。纹理的大小会影响内存和显存的占用,以及gpu采样纹理时的性能、cpu加载和带宽造成影响。
选择合适纹理大小应尽量遵循以下经验:
- 不同平台、不同硬件配置选择不同的纹理大小,Unity下可以采用bundle变体设置多套资源、通过Mipmap限制不同平台加载不同level层级的贴图。
- 根据纹理用途的不同选择不同的纹理加载方式,如流式纹理加载Texture Streaming、稀疏纹理Sparse Texture、虚拟纹理VirtualTexture等方式。
- 不能让美术人员通过增加纹理大小的方式增加细节,可以选择细节贴图DetailMap或增加高反差保留的方式。
- 在不降低视觉效果的情况下尽量减小贴图大小,最好的方式是纹理映射的每一个纹素的大小正好符合屏幕上显示像素的大小,如果纹理小了会造成欠采样,纹理显示模糊,如果纹理大了会造成过采样,纹理显示噪点。这一点做到完美平衡很难保障,可以充分利用Unity编辑器下SceneView->DrawMode->Mipmap来查看在游戏摄像机视角下哪些纹理过采样,哪些纹理欠采样,进而来调整纹理大小(红色代表过采样,需要加大纹理分辨率,或者调整mipmap层级,蓝色代表欠采样,大部分为远景,需要减少纹理分辨率)。
纹理颜色空间
默认大多数图像处理工具都会使用sRGB颜色空间处理和导出纹理。但如果你的纹理不是用作颜色信息的话,那就不要使用sRGB空间,如金属度贴图、粗糙度贴图、高度图或者法线贴图等。一旦这些纹理使用sRGB空间会造成视觉表现错误。更详细的说明参见我的PBR专栏关于线性空间与伽马空间的介绍。
纹理压缩
纹理压缩是指图像压缩算法,保持贴图视觉质量的同时,尽量减小纹理数据的大小。默认情况下我们的纹理原始格式采用PNG或TGA这类通用文件格式,但与专用图像格式相比他们访问和采样速度都比较慢,无法通用GPU硬件加速,同时纹理数据量大,占用内存较高。所以在渲染中我们会采用一些硬件支持的纹理压缩格式,如ASTC 、ETC、ETC2、DXT等。
一般来说,项目内常用的图像压缩算法为ASTC。
纹理图集
纹理图集是一系列小纹理图像的集合,Unity可以使多个网格对象对应一张纹理贴图,默认支持SpriteAtlas,但复杂模型还是需要美术同学在dcc软件中做好uv展开和uv映射
- 优点:
一是采用共同纹理图集的多个静态网格资源可以进行静态合批处理,减少DrawCall调用次数。
二是纹理图集可以减少碎纹理过多,因为他们打包在一个图集里,通过压缩可以更有效的利用压缩,降低纹理的内存成本和冗余数据。
- 缺点
美术需要合理规划模型,并且要求模型有相同的材质着色器,或需要制作通道图去区分不同材质。制作和修改成本较高。
纹理过滤
过滤方式 | 具体作用 |
---|---|
Nearest Point Filtering | 临近点采样过滤最简单、计算量最小的纹理过滤形式,但在近距离观察时,纹理会呈现块状。 |
Bilinear Filtering | 双线性采样过滤会对临近纹素采样并插值化处理,对纹理像素进行着色。双线性过滤会让像素看上去平滑渐变,但近距离观察时,纹理会变得模糊。 |
Trilinear Filtering | 三线性过滤除与双线性过滤相同部分外,还增加了Mipmap等级之间的采样差值混合,用来平滑过度消除Mipmap之间的明显变化。 |
Anisotropic Filtering | 各向异性过滤可以改善纹理在倾斜角度下的视觉效果,跟适合用于地表纹理。 |
纹理Mipmap
- Mipmap纹理
逐级减低分辨率来保存纹理副本。相当于生成了纹理LOD,渲染纹理时,将根据像素在屏幕中占据的纹理空间大小选择合适的Mipmap级别进行采样。
- 优点:
GPU不需要在远距离上对对象进行全分辨率纹理采样,因此可以提高纹理采样性能。
同时也解决了远距离下的过采样导致的噪点问题,提高的纹理渲染质量。
- 缺点:
由于Mipmap纹理要生成低分辨率副本,会造成额外的内存开销(1/3)。可以使用unity的Mipmap streaming功能,在运行时限制只采样某个级别以下的纹理,进行不同设备的不同适配。
Texture Shape
- 2D 最常用的2D纹理,默认选项
- Cube 一般用于天空和与反射探针,默认支持Default、Normal、Single Channel几种类型纹理,可以通过Assets > Create > Legacy > Cubemap生成,也可以通过C#代码 Camera.RenderToCubemap在脚本中生成
- 2D Array 2D纹理数组,可以极大提高大量相同大小和格式的纹理访问效率,但需要特定平台支持,可以通过引擎SystemInfo.supports2DArrayTextures 接口运行时查看是否支持。
- 3D 通过纹理位图方式存储或传递一些3D结构话数据,一般用于体积仿真,如雾效、噪声、体积数据、距离场、动画数据等信息,可以外部导入,也可运行时程序化创建。
Alpha Source
默认选择Input Texture Alpha就好,如果确定不使用原图中的Alpha通道,可以选择None。另外From Gray Scale我们一般不会选用。
Alpha Is Transparency
指定Alpha通道是否开启半透明,如果位图像素不关心是否要半透明可以不开启此选项。这样Alpha信息只需要占1bit。节省内存
Ignore Png file gamma
是否忽略png文件中的gamma属性,这个选项是否忽略取决于png文件中设置不同gamma属性导致的显示不正常,一般原图制作流程没有特殊设置,这个选项一般默认就好。
Read/Write
开启此选项会导致内存量增加一倍,默认我们都是不开启,除非你的脚本逻辑中需要动态读写该纹理时需要打开此选项。
Generate Mip Maps
什么时候不需要生成MipMaps?
- 2D场景
- 固定视角,摄像机无法缩放远近
- Border Mip Maps 默认不开启,只有当纹理的是Light Cookies类型时,开启此选项来避免colors bleeding现象导致颜色渗透到较低级别的Mip Level纹理边缘上
- MipMap Filtering
- Box 最简单,随尺寸减小,Mipmap纹理变得平滑模糊
- Kaiser,避免平滑模糊的锐化过滤算法。
- Mip Maps Preserve Coverage,只有需要纹理在开启mipmap后也需要做Alpha Coverage时开启。默认不开启。
- Fadeout MipMaps, 纹理Mipmap随Mip层级淡化为灰色,一般不开启,只有在雾效较大时开启不影响视觉效果。
选择合适纹理过滤的最佳经验:
- 使用双线性过滤平衡性能和视觉质量。
- 有选择地使用三线性过滤,因为与双线性过滤相比,它需要更多的内存带宽。
- 使用双线性和 2x 各向异性过滤,而不是三线性和 1x 各向异性过滤,因为这样做不仅视觉效果更好,而且性能也更高。
- 保持较低的各向异性级别。仅对关键游戏资源使用高于 2 的级别。
其他可能有问题的纹理类型
- 纹理图集大小设置不合理,图集利用率低 -> 合理规划图集
- 大量只有颜色差异的图片和UI背景贴图,可以采用9宫格缩放的图 https://docs.unity3d.com/Manual/9SliceSprites.html
- 纯色图没有使用Single Channel
- 不合理的半透明UI,占据大量屏幕区域,造成Overdraw开销 -> 重新制作
- 大量2D序列帧动画,而且图片大,还不打图集 -> 使用图集并使用合适的分辨率
- 不合理的通道图利用方案 -> 单通道
- 大量渐变色贴图,没有采用1像素过渡图,也不采用Single Channel, 粒子特效中较为常见。
Animation导入设置检查与优化
Rig标签页
Animation Type
- None 无动画
- Legacy 旧版动画,不要用
- Generic 通用骨骼框架
- Humanoid 人形骨骼框架
选择原则:
- 无动画选择None
- 非人形动画选择Generic
- 人形动画
- 人形动画需要Kinematices或Animation Retargeting功能,或者没有有自定义骨骼对象时选择Humanoid Rig
- 其他都选择Generic Rig,在骨骼数差不多的情况下,Generic Rig会比Humanoid Rig省30%甚至更多的CPU的时间。
Skin Weights
默认4根骨头,但对于一些不重要的动画对象可以减少到1根,节省计算量
Optimize Bones
建议开启,在导入时自动剔除没有蒙皮顶点的骨骼
Optimize Game Objects
在Avatar和Animatior组件中删除导入游戏角色对象的变换层级结构,而使用Unity动画内部结构骨骼,消减骨骼transform带来的性能开销。可以提高角色动画性能, 但有些情况下会造成角色动画错误,这个选项可以尝试开启但要看表现效果而定。注意如果你的角色是可以换装的,在导入时不要开启此选项,但在换装后在运行时在代码中通过调用AnimatorUtility.OptimizeTransformHierarchy接口仍然可以达到此选项效果。
Animation标签页
Resmple Curves
将动画曲线重新采样为四元数数值,并为动画每帧生成一个新的四元数关键帧,仅当导入动画文件包含尤拉曲线时才会显示此选项
Anim.Compression
- Off 不压缩,质量最高,内存消耗最大
- Keyframe Reduction 减少冗余关键帧,减小动画文件大小和内存大小。
- Keyframe Reduction and Compression 减小关键帧的同时对关键帧存储数据进行压缩,只影响文件大小。
- Optimal,仅适用于Generic与Humanoide动画类型,Unity决定如何进行压缩。
Animation Custom Properties
导入用户自定义属性,一般对应DCC工具中的extraUserProperties字段中定义的数据
- Curves Pos: 位置曲线
- Quaternion: 四元数曲线 Resample Curves开启会有
- Euler: 尤拉曲线
- Scale: 缩放曲线
- Muscles: 肌肉曲线,Humanoid类型下会有
- Generic: 一般属性动画曲线,如颜色,材质等
- PPtr:精灵动画曲线,一般2D系统下会有
- Curves Total: 曲线总数
- Constant: 优化为常数的曲线
- Dense: 使用了密集数据(线性插值后的离散值)存储
- Stream: 使用了流式数据(插值的时间和切线数据)存储
动画文件导入设置优化后信息查看原则
- 一看效果差异(与原始制作动画差异是否明显)
- 二看曲线数量(总曲线数量与各种曲线数显,常量曲线比重大更好)
- 三看动画文件大小(以移动平台为例,动画文件在小几百k或更少为合理,查过1M以上的动画文件考虑是否进行了合理优化)