Unity 中的美术制作问题

Mip Maps 是什么? 什么贴图需要开启?

Mips Maps 中文: 多级渐远纹理技术

原理: 提前用滤波处理来得到很多更小的图像, 形成一个图像倒金字塔, 每一层都是对上一层降采样的结果.

这样在实际运行时就能快速得到结果像素. 当物体远离摄像机时, 可以直接使用较小的纹理 (纹理质量差, 模糊感强), 当物体靠近时适当替换较大纹理 (纹理质量好, 模糊感较少), 以便呈现更精致的画面.

Mips Maps 开启之后会多占用 33% 的内存空间, 当物体远离时无需高精度纹理展示, 则替换为低精度纹理, 降低显存带宽, 减少渲染压力, UI 正交摄像机基本不需要用到 Mips Maps.

结论:

  1. 只要是场景中可能会出现在中远距离的物件, 他们所使用的贴图都需要开启 Mips Maps, 这样在离摄像机不同的距离时会自动切换不同的 Mip.
  2. 使用正交摄像机的 UI 所引用的纹理则需要关闭 Mip Maps.

贴图为什么要压缩? 贴图压缩格式该怎么选择?

纹理压缩可以通过减少内存来显著地提高 OpenGL 的性能, 使内存的使用效率更高.

Android 设备支持很多压缩格式, 但是这些纹理压缩格式并不是在所有的设备上都支持, 根据 GPU 芯片和OpenGL 实现的不同会略有差异, 因此需要按需选择压缩格式, 压缩格式一直在随着时代进步, 越新的压缩格式支持的设备越少, 压缩效果越好.

常见的纹理压缩格式有以下几种:

  1. DXT (Tegra) 分为 DXT1, DXT2, DXT3, DXT4, DXT5 五个级别, Terga 支持的实际上是 DXT1, DXT3 和 DXT5. 使用不是很广泛. 它支持包含 4 位或者 8 位 Alpha 通道的 RGB 纹理.

  2. PVRTC (PowerVR) 不失真压缩率最高的压缩格式. 特别的 TBDR 架构, 不渲染被遮挡的部分, 有效节省计算资源和带宽. 该格式在许多设备上面都支持, 支持每个像素 2 位或 4 位的纹理, 支持 Alpha 通道.

  3. ATC (Adreno) 该纹理压缩在许多设备上面都支持, 它支持 RGB 纹理压缩但不包含 Alpha 通道.

  4. ETC1 or RGBA16 (GLES2.0) 是大部分移动设置 GPU 都会支持的纹理标准, 但是它不支持 Alpha 通道, 压缩后会丢失透明度信息.

  5. ETC2 (GLES3.0) 补全了 ETC1 不支持 Alpha 通道的问题, 并支持更高质量的 RGBA(RGB+Alpha) 压缩.

  6. ASTC : ARM 研发的一种贴图压缩格式, 从 iOS9 (A8架构) 开始支持 ASTC 压缩格式, 相对于 ETC2/4而言, 虽然 ASTC(4X4) 的压缩比会增加到 0.25, 不过显示效果也会好很多, 而且不要求图片长宽相等且为2 的幂次方. 支持 Android OpenGL ES 3.1 和 Vulkan 设备. Android 5.0 (API 21) 和更高的版本支持这个 Android OpenGL ES 3.1 规范, 可使用此压缩格式. iPhone6 之后的设备支持此压缩格式.

结论: 由于海外版本低端机型较多, 需要兼顾安卓低端机, 因此都使用 RGBA ETC2 8 bits 压缩格式; iOS 平台舍弃 iPhone6 及以下版本的设备, 因此使用 RGBA ASTC 6X6 block 压缩格式.

什么是动态合批? 什么时候需要开启动态合批?

合批的本质是将多次绘制请求, 在允许的条件下进行合并处理, 减少 CPU 对 GPU 绘制请求的次数, 达到减少 Draw Call, 提高性能的目的. 合批的对象一般为 网格纹理. 合批也分为动态合批和静态合批. 合批的代价是内存占用会增大, 如果一大片非常密集的森林中所有的树木全部进行静态合批, 那多占用的内存可能是很恐怖的, 因此需要权衡利弊.

其中静态合批是将静态的 GameObjects 组合成一个大网格, 然后一次性进行绘制. 一般游戏中构成场景用的静止不动的 Mesh 都会设置为 Static, 进行静态合批. 前提它们共享相同的材质, 并且不移动不旋转不缩放.

无论动态合批还是静态合批都存在很大的使用限制, 使用时需要注意.

单独拿出吃鸡类型游戏中的纹理来说, 时装是不会在游戏中掉落的, 整个游戏中也不可能会改变时装, 因此时装可以使用动态合批进行合并, 但是枪械, 背包, 近战武器等它们随时可能被玩家换掉, 因为合批所使用的 API 消耗很大, 因此这些不能进行动态合批.

粒子系统什么是程序化模式? 为什么要防止程序化模式被打断?

Unity 中是自带粒子剔除系统的, 每个 Particle System 都有两种执行模式: 程序化非程序化.

  1. 程序化模式下, 粒子系统在任意时刻的状态都是可预知, 可推算的, 无论过去还是将来, 这意味着程序化模式下的粒子系统可以随时切换为任何时刻的状态.

  2. 非程序化模式下, 粒子系统的一切状态都是不可预知, 不可推算的.

粒子剔除的实现原理: 当粒子系统处于所有相机的范围之外时, 它将会被剔除, 此时粒子系统会停止更新. 当粒子系统回归视野时, 立即进行推算, 迅速切换为新时刻的状态.

这就意味着非程序化模式的粒子系统无法实现这一点, 非程序化模式的粒子系统即使是不可见时, 它也必须持续更新系统, 因为它的状态是不可预测的. 这样就会白白损失计算性能.

如何知道程序化模式被打破了?

当粒子系统不再支持程序化模式时, 检视面板会显示一个小图标, 将鼠标移动到这个图标上将提示出不再支持程序化模式的原因.

程序化被打破

以下属性会影响到粒子的程序化模式

属性

Mesh 为什么要去除未使用的顶点信息数据

主要是为了优化内存, 每个顶点色占 8B, 每个顶点的 uv 信息占 16B

内存占用情况:

顶点信息 内存占用
uv 120B
uv + uv2 136B (↑ 13%)
uv + colors 128B (↑ 6%)
uv + uv2 + colors 144B (↑ 20%)

虽然勾选了 PlayerSetting 中的 Optimize Mesh Data, 这样没有用到的顶点数据不会被打包到包体内, 但是这是 Unity 帮我们做的隐性优化, 无法直观查看, 所以直接从 Mesh 制作上变要求不能有多余的数据.

问题比较多的是有 UV2 信息的物件较多, 但是并没有使用 Lightmap 光照烘焙信息, 需要移除.

碰撞体 FBX 文件导入需要关闭法线导入选项

法线导入

仅作为碰撞模型使用的 Mesh 是不需要关注光照以及凹凸面的, 所以这类 Mesh 必须关闭法线导入.

关闭法线导入后可以大幅度地减少内存占用, 约 10% ~ 70%, 具体看模型法线数据的大小.

下表是上图中 Mesh 开启和关闭法线导入之间的差别:

开启 关闭
顶点数 8172 2468
移动设备内存占用 1126.4KB 296.6KB