Unity性能优化分析篇

性能优化是游戏项目开发中一个重要环节。游戏帧率过低,手机发烫, 包体太大,低端机上跑不起来等, 这些都需要来做优化,不管过去,现在,未来,性能优化都是永恒的话题。
而性能优化首先要掌握的是性能分析,通过分析才能发现问题所在。性能分析对于游戏开发是必备的,通过性能分析工具可以给我们提供游戏性能表现的详细信息。如果我们的游戏存在性能问题,如低帧率或者高内存占用,性能分析工具可以帮助我们发现问题的起因,并协助我们解决问题。
 

开始之前,有关性能分析需要了解的概念:

FPS(帧率)

FPS是衡量游戏性能的基本指标。在游戏中,一帧类似于动画中的一帧,FPS是指游戏运行时每秒所运行的帧数,也可以理解为每秒渲染的画面数。
通常FPS越高,表明游戏性能运行越好,对于大多数当前游戏的目标是帧率60FPS,通常来说,帧率在30FPS以上是可以接受的,特别是移动游戏,或者不需要快速反应互动的游戏,对于在VR游戏中,则至少需要90FPS。
实际上FPS并不是衡量游戏稳定体验的理想指标。考虑以下情况:在运行时的前0.75s内渲染了59帧。然后接下来的1帧需要0.25s才能渲染完毕。虽然是60fps,但实际上会让玩家感觉卡顿。对于我们来说更有用的是渲染一帧需要多少毫秒。
渲染一帧,Unity必须执行很多不同的任务。简单的说,Unity必须更新游戏的状态,获取游戏的快照并且把快照画到屏幕上。有一些任务是在每一帧都执行的,包括读取用户输入,执行脚本,运行光照计算等。除此之外,有许多操作是在一帧执行多次的,例如物理运算。当所有这些任务都执行的足够快时,我们的游戏才会有稳定且可接受的帧率。当这些任务执行的不够快时,渲染一帧将花费太长的时间,并且帧率会因此下降。
知道哪些任务花费了太长的时间执行,对于我们怎样去解决性能问题是十分关键的。一旦我们知道了哪些任务降低了帧率,我们就可以尝试去优化游戏的那一部分。这就是为什么性能分析工具这么关键:性能分析工具告诉我们在一帧中每个任务花费了多长时间。


VSync(垂直同步)

VSync将应用程序的帧率与显示器的刷新速率同步。这意味着,如果您有一个60Hz的显示器,并且游戏的帧预算在16.66ms内,则它会强制以60fps运行,而不允许更快。将帧率与显示器的刷新速率同步,可以减轻GPU的负担并解决屏幕撕裂等视觉图像瑕疵。在Unity中,通过Quality settings 可以设置VSync Count (Edit > Project Settings > Quality)。
QualitySettings.vSyncCount有三种选项

  • Don't Sync(不同步) 
  • Every V Blank(每一个垂直同步) 
  • Every Second V Blank(每一秒的垂直同步) 

移动平台忽视 QualitySettings.vSyncCount。仅使用 Application.targetFrameRate 控制帧率。移动平台的最大帧率就是屏幕的刷新率,移动平台上的默认帧率通常为每秒 30 帧。

垂直同步对 FPS 的影响

我们平时用的电脑显示器,一般屏幕的刷新率都是80HZ上下,那么显卡会按照每秒80HZ来发送一个垂直同步信号。

  • 开启垂直同步:显卡绘制完一屏图像后,需要等待80HZ垂直同步信号的到达,才可以开始绘制下一屏。这样游戏自然受到刷新率运行的制约。
  • 关闭垂直同步:那么游戏中显卡绘制完一屏图像后,显卡和显示器无需等待垂直同步信号达到,就可以开始下一屏的绘制,展示了显卡的实力。

但是不要忘记,正是因为垂直同步的存在,才能使得游戏进程和显示器刷新率同步,使得画面更加平滑和稳定。取消了垂直同步信号,固然可以换来更快的速度,但是在图像的连续性上势必打折扣。这也正是很多朋友抱怨关闭垂直后发现画面不连续的理论原因。
 

Unity Profiler

Profiler是Unity内置的强大的性能分析工具,通过Profiler,我们可以了解到cpu使用情况,gpu使用情况,渲染,内存使用情况,声音,物理,网络,UI等等。还可以进行录制数据,分析每帧的运行情况。可以在Unity Editor中进行分析,也可以在目标平台上分析,连接真机,真实了解游戏运行情况。

The CPU usage profiler

当我们查看Profiler窗口的上部时,可以看到完成每帧的任务花费了多少cpu时间。
在CPU usage左侧,可以看到不同颜色的分类块,可以点击显示隐藏你感兴趣的分类,右侧显示各分类的耗时,可以根据颜色块的大小清晰的了解性能的瓶颈所在。最下面可以详细的了解所有任务的耗时,可以精确到各大个函数的耗时,可以根据排序快速定位问题所在,也可以搜索你关心的函数。

渲染分析

渲染是导致性能问题的常见原因。在尝试修复渲染问题前,确定是CPU受限还是GPU受限非常重要,这些情况需要不同的解决方法。 简单来说,CPU负责确定必须绘制什么,GPU负责绘制它。
如果游戏中因为CPU执行渲染任务耗时太久而导致帧渲染时间过长,我们称其为 CPU受限(CPU Bound)。
如果游戏中因为GPU执行渲染任务耗时太久而导致帧渲染时间过长,我们称其为 GPU受限(GPU Bound)。

GPU受限

通过GPU usage快速地判断游戏是否GPU受限。但并非所有设备和驱动程序都支持此分析器。在检查GPU受限之前,需要先检查GPU usage是否适用于我们的目标设备。如果添加GPU usage后有数据意味目标设备支持GPU usage。
如果GPU时间超过CPU时间,可以确定在该点上已经GPU受限。

如果目标硬件不支持GPU usage,仍然可以确定游戏是否GPU受限。可以通过观察CPU使用情况来判断。如果发现CPU正在等待GPU完成其任务,这意味着游戏GPU受限。
如果主线程在Profiler标记(例如Gfx.WaitForPresentOnGfxThread)中花费大量时间,而渲染线程同时显示Gfx.PresentFrame或<GraphicsAPIName>.WaitForLastPresent等标记,则应用程序出现了GPU受限。

CPU受限

如果尚未确定性能问题的原因,我们继续分析基于CPU的渲染问题。

点击选择CPU usage。
在分析器窗口的顶部,CPU usage显示其随时间变化的数据。查看表示渲染的图表中的彩色部分。可以通过在关键字中单击名称旁边的彩色方块来隐藏或显示图表中的数据。
如果一帧中大部分时间由渲染所占用,这表明渲染可能是问题的原因。可以通过以下步骤深入分析数据来确认:
查看分析器窗口底部显示当前选定帧和分析器详细信息的区域。
在该区域左上角的下拉菜单中选择“Hierarchy”。
选择“Time ms”列,按时间(毫秒)对函数进行排序。
单击列表中的顶部函数进行选择。
如果选定的函数是渲染函数,CPU分析器图表将通过Rendering进行突出显示。这种情况意味着与渲染相关的操作导致性能问题,此时游戏处于CPU受限状态。请注意函数名称和执行函数的线程,这些信息将在修复问题时很有用。 

解决GPU受限时的渲染问题

优化填充率
填充率指GPU每秒能够渲染的屏幕像素数量,它是引起GPU的性能问题的最常见因素,尤其是在移动设备上。
填充率相关的优化手段:

  • 优化片元着色器(Fragment Shader)
  • 减少重绘(Overdraw)
  • 优化减少后处理(Image Effects)

优化显存带宽(Memory Bandwidth
显存带宽指GPU对其专用的内存的读写速率。如果游戏出现带宽受限,通常是因为使用了太大的纹理(Texture)。

优化顶点处理(Vertex Processing)
顶点处理指GPU渲染Mesh中的每个顶点使所做的工作。顶点处理的开销与两个因素有关:需要进行渲染的顶点的数量和对每个顶点所要进行的操作。

降低屏幕渲染分辨率,通常这是有效的手段。也可以通过此方法来检验是否GPU受限。

解决CPU受限时的渲染问题

向GPU发送指令的时间开销是引起CPU Bound的最常见原因,向GPU发送指令的过程中,开销最大的操作是SetPass Call。
通常,有3种 降低Batch和SetPass Call数目的方法:

  • 降低需要渲染的对象的数量,可以同时减少Batch和SetPass Call。
  • 降低每个对象需要被渲染的次数,可以减少SetPass Call。
  • 将对象合并到更少的批处理当中,可以减少Batch。

CPU与GPU并不各自孤立:

如果 CPU 在物理计算和脚本运行要花很多时间,那么即使 Shader 优化得再好,也不会提高帧率;
如果 GPU 处理 Shader 消耗大量时间,那么即使优化物理系统和脚本也不会对提高帧率有什么帮助。
当 CPU 压力大,而 GPU 压力小时,就不应该采取一些加大 CPU 压力以减少 GPU 压力的方法。反之亦然。

因此我们要分析找到影响运行性能的短板。

垂直同步的影响

垂直同步(VSync)用来同步游戏的帧率和屏幕的刷新率。垂直同步会影响游戏的帧率,在Profiler窗口中可以看到影响。如果我们不是特别确定问题所在,垂直同步的影响可能看起来像性能问题,我们可以选择在CPU usage profiler中隐藏Vsync信息,也可以在Quality settings 关闭垂直同步。
 

Frame Debugger

Frame Debugger是Unity另一个常用的性能分析工具,它能够让我们详细查看某一帧的渲染过程。只需在菜单栏选择"Window > Analysis > Frame Debugger"即可打开。
在游戏运行中,点击Frame Debugger的Enable按钮,游戏将自动暂停,并在界面中展示当前帧的渲染细节。
界面左侧列表以层级视图形式显示绘制调用(DrawCall、事件等),右侧面板提供有关绘制调用的更多信息,例如几何体细节和用于渲染的着色器。
选中某一渲染步骤后,界面右侧将显示该步骤的详细信息,包括渲染的目标,使用的Shader以及Shader属性等详细信息。同时,Game视图中也会展示该步骤渲染的结果。
Frame Debugger在优化DrawCall和调试Shader时非常有用。

Memory Profiler

Memory Profiler是Unity分析内存性能的进阶工具,可描绘更全面的内存使用情况,使得性能优化与内存问题检测更为方便快捷。您可以使用它来检查Unity应用程序和Unity编辑器的内存使用情况。您可以使用它来捕获、检查和比较内存快照。快照记录了当内存分析器捕获快照时,应用程序使用的内存是如何组织的。Memory Profiler还提供本机和托管内存分配的概述,以评估应用程序的内存使用情况,并识别潜在的问题,如内存泄漏。
要避免应用在容量有限的设备上出现内存溢出崩溃的问题,那么内存优化将是非常关键的一步。此外,如果项目需要发布至多个平台,开发者则需要调整内存占用,以最大化利用每个平台。
Memory Profiler让面临这些挑战的用户能够截取并审查游戏在特定时间点的内存占用。
借助这些“快照”,你可以找出游戏中最占内存的部分或崩溃的原因。

Memory Profiler需要使用Package Manager安装,Package Manager窗口左上角点击“+”,Add pacakge by name : com.unity.memoryprofiler
 

Gmae View Statistics

在Unity的Game视图包括一个统计窗口,显示您的应用程序在运行模式下的实时渲染信息。要打开此窗口,请单击右上角的 Stats 按钮。该窗口会在 Game 视图右上角叠加显示。它包含的统计信息对于优化性能很有用。显示的具体统计信息根据构建目标而有所不同。

Statistics 窗口的字段信息:

  • FPS:当前 Unity 每秒能够绘制的帧数
  • CUP main:处理一帧所花费的总时间。包括 Unity 处理应用程序的帧更新所花费的时间,以及 Unity 在编辑器中更新场景视图、更新其他编辑器窗口或处理仅编辑器任务所花费的时间。
  • CUP render thread:渲染一帧所花费的时间。这个数字包括Unity处理游戏视图的帧更新所花费的时间;它不包括Unity在编辑器中花费的时间。
  • Batches:Unity 在一帧内处理的批次总数。该数字包括静态和动态批次。
  • Saved by batching:    Unity 合并的批次数。为确保良好的批处理,应尽可能在不同游戏对象之间共享材质。更改渲染状态会将批次分成具有相同状态的组。
  • Tris:Unity 在一帧内处理的三角形数。在针对低端硬件进行优化时,这一点非常重要。
  • Verts:Unity 在一帧内处理的顶点数。在针对低端硬件进行优化时,这一点非常重要。
  • Screen:屏幕的分辨率及其使用的内存量。
  • SetPass calls:    Unity 在一帧中切换用于渲染游戏对象的着色器通道的次数。一个着色器可能包含多个着色器通道,每个通道以不同的方式渲染场景中的游戏对象。每个 pass 都需要 Unity 绑定一个新的着色器,这可能会带来 CPU 开销。
  • Shadow casters:在一帧中投射阴影的游戏对象的数量。
  • Visible skinned meshes:Unity 在帧中渲染的带蒙皮的网格渲染器的数量。
  • Animation components playing:帧期间播放的动画数量(Animation)。
  • Animatior components playing:帧期间播放的动画数量(Animatior)。

Scene View Draw Mode

在Unity的Scene视图右上角最左侧,可以改变Scene的绘制模式,不同的绘制模式有时对性能分析也有所帮助。

Shadow Cascades

使用颜色可以采用不同的级联级别显示场景的各个部分。此模式有助于正确设置阴影距离、级联计数和级联分割比率。请注意,此可视化方法会使用通常大于阴影距离的 Scene 视图远平面,因此如果要将摄像机的游戏内行为与小远平面匹配,可能需要缩短阴影距离。

Overdraw

将对象渲染为透明的“轮廓”。透明的颜色会累积,因此可以轻松找到一个对象绘制在另一个对象上的位置。颜色越亮表示Overdraw越高,可以简单的看出哪些地方过渡绘制。
比如在此模式下查看特效,如果发现特别亮,则说明此特效Overdraw过高,应考虑优化。

Mipmaps

使用颜色代码显示理想的纹理大小:红色表示纹理大于必要值(在当前距离和分辨率下) ;蓝色表示纹理可以更大。当然,理想的纹理大小取决于游戏运行的分辨率以及摄像机与特定表面的接近程度。
比如在此模式下浏览场景,如果发现有些地方特别红,则说明这个地方的贴图Mipmap不合理,可以考虑压缩贴图。

Unity是个多平台开发引擎,除了其内置的性能分析工具,也可以通过导出对应的平台工程,使用对应平台原生的性能分析工具,如android studio, xcode

除了在运行时进行性能分析,我们也可以在非运行时对资源进行检测,对性能优化也是十分有帮助的。

UWA本地资源检测

UWA,https://www.uwa4d.com  致力于游戏/VR应用性能诊断与优化,这里主要介绍下它的本地资源检测。

UWA本地资源检测是对游戏、VR等项目工程的资源、代码和设置等进行自动检测的服务,是项目研发持续集成、持续交付流程中的重要一环,旨在为游戏研发制定资源与代码规范,帮助研发团队快速发现和解决项目中的性能问题以及可能出现的异常、错误。研发团队可通过日常的自动检查,规范程序、美术成员的开发,从源头上对项目进行优化,规避风险,节约成本。

到官网下载SDK后,解压放在Editor,即可使用,它有很多类型的检测,每次检测扫描后会生成一份本地数据,需要使用上传工具上传数据到网站后台,然后登陆网站,可以查看分析报告。

详细使用请参考:https://blog.uwa4d.com/archives/UWA_Pipeline40.html

Unity UPR 静态资源检测

Unity UPR,https://upr.unity.cn  是Unity官方的专业团队,为企业用户提供真人真机测试、远程报告诊断、自动化集成以及私有云部署等定制化服务。这里主要介绍下它的静态资源检测
UPR 静态资源检测,不依赖 Unity Editor,通过无需安装的可执行程序,极快速的进行资源扫描。UPR 可以将扫描结果直观的展示出来,帮助开发者尽早发现资源文件中存在的问题。

下载工具后解压,使用assetcheck.exe命令行生成报告数据,可自行上传数据到网站查看报告,也可提前在网站建好项目,工具会自动上传。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/143817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BIO、NIO、AIO三者的区别及其应用场景(结合生活例子,简单易懂)

再解释三者之前我们需要先了解几个概念&#xff1a; 阻塞、非阻塞&#xff1a;是相较于线程来说的&#xff0c;如果是阻塞则线程无法往下执行&#xff0c;不阻塞&#xff0c;则线程可以继续往下 执行。同步、异步&#xff1a;是相较于IO来说的&#xff0c;同步需要等待IO操作完…

Outlook邮件视图设置怎么修复

故障现象 Outlook邮箱显示不对 故障截图 故障原因 邮箱视图设置不对 解决方案 1、在Outlook上方工具栏找到视图按钮&#xff0c;以此选择视图→视图设置→列&#xff0c;打开选择的列 2、在视图→邮件预览里面&#xff0c;选择1行&#xff0c;在阅读格式选择靠右&#xff…

AI创作系统ChatGPT网站源码+支持最新GPT-Turbo模型+支持DALL-E3文生图/AI绘画源码

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

Nodejs操作缓存数据库-Redis

Hi I’m Shendi Nodejs专栏 Nodejs操作缓存数据库-Redis 在服务端开发中&#xff0c;缓存数据库也是不可或缺的&#xff0c;可以提高程序并发以及方便后续扩展&#xff0c;而目前最常用的莫过于Redis了 安装依赖 和之前的mysql一样&#xff0c;redis的依赖最常用的就是redis …

自学SLAM(8)《第四讲:相机模型与非线性优化》作业

前言 小编研究生的研究方向是视觉SLAM&#xff0c;目前在自学&#xff0c;本篇文章为初学高翔老师课的第四次作业。 文章目录 前言1.图像去畸变2.双目视差的使用3.矩阵微分4.高斯牛顿法的曲线拟合实验 1.图像去畸变 现实⽣活中的图像总存在畸变。原则上来说&#xff0c;针孔透…

51单片机应用从零开始(三)

51单片机应用从零开始&#xff08;一&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;二&#xff09;-CSDN博客 详解 KEIL C51 软件的使用建立工程-CSDN博客 详解 KEIL C51 软件的使用设置工程编绎与连接程序-CSDN博客 目录 1. 用单片机控制第一个灯亮 2. 认识单片…

leetcode:476. 数字的补数

一、题目 476. 数字的补数 - 力扣&#xff08;LeetCode&#xff09; 函数原型&#xff1a; int findComplement(int num) 二、思路 将num的每一位取出来&#xff0c;取反后&#xff0c;乘以2的位次方&#xff0c;最终所有结果相加即可得到结果。 如何取出num的每一位&#xff1…

<MySQL> 查询数据进阶操作 -- 联合查询

目录 一、什么是笛卡尔积&#xff1f; 二、什么是联合查询&#xff1f; 三、内连接 3.1 简介 3.2 语法 3.3 更多的表 3.4 操作演示 四、外连接 4.1 简介 4.2 语法 4.3 操作演示 五、自连接 5.1 简介 5.2 自连接非必要不使用 六、子查询(嵌套查询) 6.1 简介 6.…

电源电压范 围宽、功耗小、抗干扰能力强的国产芯片GS069适用于电动工具等产品中,采用SOP8的封装形式封装

GS069电动工具直流调速电路是CMOS专用集成电路&#xff0c;具有电源电压范 围宽、功耗小、抗干扰能力强等特点。通过外接电阻网络&#xff0c;改变与之相接 的VMOS 管的输出&#xff0c;达到控制电动工具转速的作用。该电路输出幅值宽&#xff0c; 频率变化小&#xff0c;占空比…

自己动手实现一个深度学习算法——六、与学习相关的技巧

文章目录 1.参数的更新1&#xff09;SGD2&#xff09;Momentum3&#xff09;AdaGrad4&#xff09;Adam5&#xff09;最优化方法的比较6&#xff09;基于MNIST数据集的更新方法的比较 2.权重的初始值1&#xff09;权重初始值不能为02&#xff09;隐藏层的激活值的分布3&#xff…

04-学成在线之系统管理服务模块之查询数据字典表中的内容,前后端联调测试

前后端联调 配置前端环境 实际开发中先由后端工程师将接口设计好并编写接口文档并交给前端工程师&#xff0c;前后端的工程师就开始并行开发 前端开发人员先自己mock数据即使用假数据进行开发,当后端代码完成后前端工程师尝试请求后端接口获取数据然后渲染到页面 第一步: 首…

计算机网络之物理层

物理层 1. 物理层的基本概念 2.物理层下面的传输媒体 传输媒体可分为两类&#xff0c;一类是导引型传输媒体&#xff0c;另一类是非导引型传输媒体。 3.传输方式 3.1 串行传输和并行传输 串行传输&#xff1a;串行传输是指数据是一个比特依次发送的&#xff0c;因此在发送端…

C/C++轻量级并发TCP服务器框架Zinx-框架开发002: 定义通道抽象类

文章目录 2 类图设计3 时序图数据输入处理&#xff1a;输出数据处理总流程 4 主要实现的功能4.1 kernel类&#xff1a;基于epoll调度所有通道4.2 通道抽象类&#xff1a;4.3 标准输入通道子类4.4 标准输出通道子类4.5 kernel和通道类的调用 5 代码设计5.1 框架头文件5.2 框架实…

wx.canvasToTempFilePath生成图片保存到相册

微信小程序保存当前画布指定区域的内容导出生成指定大小的图片&#xff0c;记录一下 api&#xff1a;wx.canvasToTempFilePath 效果&#xff1a; 代码&#xff1a;wxml <canvas style"width: {{screenWidth}}px; height: {{canvasHeight}}px;" canvas-id"my…

2023.11.15 每日一题(AI自生成应用)【C++】【Python】【Java】【Go】 动态路径分析

目录 一、题目 二、解决方法 三、改进 一、题目 背景&#xff1a; 在一个城市中&#xff0c;有数个交通节点&#xff0c;每个节点间有双向道路相连。每条道路具有一个初始权重&#xff0c;代表通行该路段的成本&#xff08;例如时间、费用等&#xff09;。随着时间的变化&am…

CentOS修改root用户密码

一、适用场景 1、太久没有登录CentOS系统&#xff0c;忘记管理密码。 2、曾经备份的虚拟化OVA或OVF模板&#xff0c;使用模板部署新系统后&#xff0c;忘记root密码。 3、被恶意攻击修改root密码后的紧急修复。 二、实验环境 1、VMware虚拟化的ESXI6.7下&#xff0c;通过曾经…

javaweb---maventomcat使用教程

文章目录 今日内容0 复习昨日1 Maven1.0 引言1.1 介绍1.2 下载1.3 安装1.3.1 解压1.3.2 配置环境变量1.3.3 测试 1.4 仓库1.5 Maven配置1.5.1 修改仓库位置1.5.2 设置镜像 2 IDEA - MAVEN2.1 idea关联maven2.2 创建java项目2.3 java项目结构2.4 pom2.5 导入依赖2.5.1 查找依赖2…

如何计算掩膜图中多个封闭图形的面积

import cv2def calMaskArea(image,idx):mask cv2.inRange(image, idx, idx)contours, hierarchy cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)for contour in contours:area cv2.contourArea(contour)print("图形的面积为", area) image是…

C语言从入门到精通之【char类型】

char类型用于储存字符&#xff08;如&#xff0c;字母或标点符号&#xff09;&#xff0c;但是从技术层面看&#xff0c;char是整数类型。因为char类型实际上储存的是整数而不是字符。计算机使用数字编码来处理字符&#xff0c;即用特定的整数表示特定的字符。 char类型占1个字…

2023年09月 Python(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 阅读以下代码,程序输出结果正确的选项是?( ) def process_keywords(keywords_list):unique_keywords = list(set(keywords_list))