目录
6.3.8 优化Unity UI
1.使用更多画布
画布组件的主要任务是管理在层次窗口中绘制UI元素的网格,并在发出渲染这些元素所需的DrawCall。
画布的另一个重要作用是将网格合并进行批处理(条件是这些网格的材质相同),以降低DrawCall数。然而,当画布或其子对象发生变动时,这称为”画布污染“。当画布污染后,就需要为画布上的所有UI对象重新生成网格,才可发出DrawCall。
只有很少变动(如更改UI元素的颜色)不会找出画布污染。
一个常见的错误是在单个画布中构建整个游戏的UI并保持这种方式,因为游戏代码及其UI会让这变得越来越复杂。
将UI拆分为多个画布,可以将工作负载分离开,简化单个画布所需的任务。
2.在静态画布和动态画布中分离对象
基于元素更新的时间给元素分组:静态(背景图片、标签),偶尔动态(UI按钮),连续动态(动画),应该尝试将3个组的UI元素拆分到3个不同的画布。
3.为无交互的元素禁用Raycast Target
4.通过禁用父画布来隐藏UI元素
UI使用单独的布局系统处理某些元素类型的重新生成工作,其操作方式类似于污染画布。启用和禁用布局系统的组件(如UIImage,UIText,LayoutGroup)会导致污染画布。
如果想要禁用UI的一部分,只要禁用其子节点的画布组件,就可以避免布局系统的这种昂贵的重新生成调用。禁用画布,只会停止UI的渲染和交互,各种更新调用(Update,FixedUpdate,LateUpdate,Coroutine)应继续正常执行,需要手动禁用。
5.避免Animator组件
应该完全避免使用Animator组件,Unity从未打算将它用于UI系统,而应使用自己的动画内插方法或使用可实现此类操作的程序
6.为World Space画布显式定义Event Camera
在WordSpace画布的给定帧期间,EventCamera的访问频率相当高,这意味着将此属性设置为null,将导致巨大的性能损失而没有真正的好处。应手动设置。
7.不要使用alpha隐藏UI元素
color属性中alpha值为0的UI元素仍会发出DrawCall。应该更改
8.优化ScrollRect
- 确保使用RectMask2D
- 在ScrollRect中禁用PixelPerfect
- 手动停用SrollRect活动
9.使用空的UIText元素进行全屏交互
10.查看Unity UI源代码
https://bitbucket.org/Unity-Technologies/ui/ 没有了
https://github.com/Unity-Technologies/uGUI 2年前更新的 2019.1
11.查看文档
https://learn.unity.com/tutorial/optimizing-unity-ui#
6.3.9 优化着色器
片元着色器是填充率和内存带宽的主要消耗者。消耗成本取决于它们的复杂度:纹理采样的数量、使用的数学函数量以及其他因素。GPU的并行特效(在数百个线程之间共享整个作业的小部分)意味着线程中的任何瓶颈都将限制每一帧中通过该线程推送的片元数量。
一个经典的比例是汽车装配线。
GPU并行处理器以类似的方式工作:每个处理器线程都是一个装配线,每个处理阶段都是一个团队,每个片元都是需要构建的东西。如果线程在处理单个阶段上花费了很长时间,那么在每个片元上都会浪费时间。这种延迟将成倍增加,以至于将来通过同一线程的所有片元都将被延迟。
着色器的编程和优化是游戏开发的一个非常小众的领域。
1.考虑使用针对移动平台的着色器
2.使用小的数据类型
3.在重排(Swizzling)时避免修改精度
4.使用GPU优化的辅助函数
使用UnityCG.cginc中的库函数
5.禁用不需要的特性
6.删除不必要的输入数据
7.只公开所需的变量
8.减少数学计算的复杂度
9.减少纹理采样
10.避免条件语句
if-else 数值上的可以转换成数学公式的
11.减少数据依赖
编译器尽力将着色器代码优化为更友好的GPU底层语言,这样,在处理其他任务时,就不需要等待获取数据。
无法编译的长数据依赖链绝对会破坏着色器的性能。
12.表面着色器
表面着色器的设计初衷是高效地处理常见情况,而最好的优化方式则是通过编写自定义的着色器来实现。
13.使用基于着色器的LOD
可以强制Unity使用更简单的着色器来渲染远端对象,这是一种节省填充率的有效方法。
LOD关键字可以在着色器中用来设置着色器支持的屏幕尺寸参数。
https://docs.unity3d.com/Manual/SL-ShaderLOD.html
6.3.10 使用更少的纹理数据
使用16位纹理来获得质量没有明显下降的图形。
MipMaps是减少在VRAM和纹理缓存之间来回推送的纹理数据量的另一种好方法。
6.3.11 测试不同的GPU纹理压缩格式
Unity中有不同的纹理压缩格式,这能减少程序的磁盘空间占用(可执行文件大小)和运行时的CPU、内存的使用率。这些压缩格式都是为具体平台的GPU架构设计的。
6.3.12 最小化纹理交换
1.直接降低纹理分辨率
2.采用不同的材质和着色器数学在不同的网格上重复使用纹理
3.将纹理组合到图集,以减少纹理交互的次数
4.从应用程序中完全删除纹理
6.3.13 VRAM限制
1.用隐藏的GameObject预加载纹理
2.避免纹理抖动
必须确保在任何给定时刻使用的纹理总量都低于目标硬件的可用VRAM
6.3.14 照明优化
1.谨慎地使用实时阴影
阴影很容易成为DrawCall和填充率的最大消耗者之一,因此应该花时间调整这些设置,直到获得所需的性能和/或图形质量。
Edit|Project Settings|Quality|Shadows:Shadow Distance、Shadow Resolution、Shadow Cascades
影阴影和软阴影的唯一的区别是着色器比较复杂。
2.使用剔除遮罩
灯光组件的Culling Mask属性是基于层的遮罩,可用于限制受给定灯光影响的对象。
3.使用烘培的光照纹理
与在运行时生成光照和阴影相比,在场景中烘培光照和阴影对处理器的计算强度要低很多。
6.3.15 优化移动设备的渲染性能
1.避免alpha测试
在大多数情况下应该利用alpha混叠来避免alpha测试。
2.最小化DrawCall
移动应用程序在DrawCall上通常比填充率更容易发生瓶颈。这并不是说可以忽略填充率,而说明任何质量合格的移动应用从一开始就必须实现网格组合、批处理和图集绘制技术。延迟渲染也是降低DrawCall次数的首先技术。
3.最小化材质数量
这个问题和批处理和图集的概念密切相关
4.最小化纹理大小
与桌面GPU相比,大多数移动设备的纹理缓存都非常小。
对GPU而言太大的纹理将在初始化期间被CPU压缩。
5.确保纹理时方形且大小为2的幂次方
6.在着色器中尽可能使用最低的精度格式
6.4 本章小结
处理算法的改进,我们实现的每个性能增强都会带来一些相关的成本,我们必须愿意承受消除瓶颈而带来的这些成本。应该随时准备好多种技术的实施,直到将这些技术全部用完,并可能花费大量额外的开发时间来实现和测试一些性能增强特性。
第7章 虚拟速度和增强加速度
7.1 XR开发
在Unity中开发XR产品包括把某个XR的软件开发工具包(SDK)导入到Unity中,执行一些特定的API调用,以在运行时配置和使用平台。
XR平台的主要吸引力在于它的沉浸性体验,没有什么比帧丢失、闪烁或任何类型的应用程序故障能更快中断这种沉浸。
7.1.1 仿真
Hololens的Simulation
7.1.2 用户舒适度
事实上,由于对自己游戏的熟悉,开发人员是最有偏见的测试人员。
用户不适:运动眩晕、眼睛疲劳、迷失方向。
7.2 性能增强
7.2.1 物尽其用
VR应用中需要达到的最重要性能指标是高FPS值,最好是90FPS或更高。
前面介绍的性能增强功能和方案在XR中大部分都适用。
7.2.2 单通道立体渲染和多通道立体渲染
多通道渲染将场景渲染为两个不同的图形,分别为每只眼睛显示一个图像。单通道立体渲染将两个图像合并为一个双倍宽度的RenderTexture,仅为每只眼睛显示一半。
单通道渲染开启后,屏幕空间发生变化。
7.2.3 应用抗锯齿
抗锯齿显著提高了XR项目的保真度,应在项目早期开始应用。
7.2.4 首选前向渲染
延迟渲染和抗锯齿有点冲突
7.2.5 VR的图像效果
在VR中法线纹理应用的效果容易发生错误。应使用置换纹理、曲面分形和/或视差纹理来创建更可信的深度外观。
7.2.6 背面剔除
7.2.7 空间化音频
7.2.8 避免摄像机物理碰撞
在XR中,用户可以通过物体移动摄像头,这会破坏沉浸感
7.2.9 避免欧拉角
避免任何类型的定向行为使用欧拉角。使用四元数,避免万向锁。
7.2.10 运动约束
7.2.11 跟上最新发展
7.3 小结