Unity的Vsync Count垂直同步原理剖析

本文详细解释了垂直同步的概念及其在游戏中的应用,包括如何通过垂直同步防止画面撕裂、提升游戏流畅度等内容。
 大家在做Unity游戏开发 或 玩游戏的时候应该注意到了“垂直同步”这个名词。现在很多游戏特效设置了里边都有这个选项,那么到底是打开还是关闭垂直同步? 垂直同步是什么意思 ,有什么作用呢?
 
      提示:如何打开或关闭垂直同步
进入游戏后在游戏的画面设置里边一般都会有垂直同步的开关选项的,如图:

垂直同步是什么意思,到底是打开还是关闭垂直同步?
 
       垂直同步是什么意思?

       垂直同步又称场同步(Vertical Hold),从CRT显示器的显示原理来看,单个象素组成了水平扫描线,水平扫描线在垂直方向的堆积形成了完整的画面。显示器的刷新率受显卡DAC控制,显卡DAC完成一帧的扫描后就会产生一个垂直同步信号。我们平时所说的打开垂直同步指的是将该信号送入显卡3D图形处理部分,从而让显卡在生成3D图形时受垂直同步信号的制约。

       垂直同步的作用:
 
      简单来说垂直同步的作用是防止画面撕裂。因为画面的渲染不是整个画面一起渲染的,是逐行或者逐列渲染。如果关闭垂直同步,而 电脑配置 不够,则画面在高速移动中会出现这一画面还没渲染完成就开始下一画面的撕裂情况。
 
       打开与关闭垂直同步的主要区别在于那些高速运行的游戏,比如实况,FPS游戏,打开后能防止游戏画面高速移动时画面撕裂现象,当然打开后如果你的游戏画面FPS数能达到或超过你显示器的刷新率,这时你的游戏画面FPS数被限制为你显示器的刷新率。你会觉得原来移动时的游戏画面是如此舒服,如果达不到会出现不同程度的跳帧现象,FPS与刷新率差距越大跳帧越严重。关闭后除高速运动的游戏外其他游戏基本看不出画面撕裂现象。关闭此选项画面流畅程度会有一定的提高。
 
       为什么是否关闭垂直同步信号会影响我们CS中的fps数值?道理一点都不复杂,首先我们平时运行操作系统一般屏幕刷新率是多少?大概一般都是在85上下吧,那么显卡就会每按照85的频率时间来发送一个垂直同步信号,信号和信号的时间间隔是85的分辨率所写一屏图像时间。
 
      如果我们选择“等待垂直同步信号”(也就是我们平时所说的“垂直同步打开”),那么在游戏中,或许强劲的显卡迅速的绘制完一屏的图像,但是没有垂直同步信号的到达,显卡无法绘制下一屏,只有等85单位的信号到达,才可以绘制。这样fps自然要受到操作系统刷新率运行值的制约。
 
      而如果我们选择“不等待垂直同步信号”(也就是我们平时所说“关闭垂直同步”),那么游戏中作完一屏画面,显卡和显示器无需等待垂直同步信号,就可以开始下一屏图像的绘制,自然可以完全发挥显卡的实力。
 
      但是,不要忘记,正是因为垂直同步的存在,才能使得游戏进程和显示器刷新率同步,使得画面平滑,使得画面稳定。取消了垂直同步信号,固然可以换来更快的速度,但是在图像的连续性上,性能势必打折扣。这也正是很多朋友抱怨关闭垂直后发现画面不连续的理论原因!

 
       什么是画面撕裂:
 
      画面撕裂可以简单的理解为,这一帧的数据打进显示器,上一帧的还没消去。结果就是画面上面和下面显示不同步。
 
      其实图像显示是一张一张的图片高速的覆盖,形成影像。而通常说的帧数,就是指每秒刷新图像的次数。计算机算出图片结果就要渲染在屏幕上,而渲染和算出的花费时间是不一样的,
通常算的会非常快,而渲染要慢的多。开了垂直同步,计算机就会等待上一张图片渲染完成后才会发出开始下一张渲染的命令;不开垂直同步,那么计算机就急不可待的想把算好的结果渲染在屏幕上,这样就容易出现上一张还没有渲染完,又来新的图来覆盖,时间差大到一定程度就会出现屏幕撕裂。
 
      下边是一张关于画面撕裂的例子(实际情况,没有图中这么夸张的)
 

       什么情况下打开或关闭垂直同步:
 

      在玩fps类游戏时,如果帧数过高画面有撕裂的话就会感觉头痛头晕。此时就需要打开垂直同步,以保持画面输出的稳定。一般游戏建议开垂直,保护显卡,降低功耗,而普通的60帧与在高的帧数已经无法用肉眼直接看出区别了,不影响游戏体验。除非你的显卡性能非常低,不开垂直远远不能达到屏幕刷新率的帧数,这种情况下关闭垂直同步,可以一定程度上减小显卡的负担,让画面更加流畅一些。

       所以说一些低配置的手机,开垂直同步实在是蛋疼,建议关闭。

<think>我们正在讨论如何在Unity中检测垂直同步造成的CPU等待。根据引用[1]中的信息,Unity的Profiler工具可以帮助我们分析性能问题,特别是其中提到的"Gfx.WaitForPresent"指标,它表示CPU等待垂直同步的时间。 具体步骤: 1. 打开Profiler:Window -> Analysis -> Profiler 2. 由于在编辑器中调试可能不准确,建议打包并在设备上运行。打包时开启开发模式(Development Build)和自动连接Profiler(Autoconnect Profiler)以及深度分析(Deep Profiling)。 3. 在Profiler窗口中,选择CPU Usage模块,并查看时间线。在时间线的下方,我们可以看到每一帧的时间分布。 4. 在时间分布中,有一个部分叫做"Sync",这个部分表示同步等待的时间,其中就包括等待垂直同步的时间。引用[1]中提到,当开启垂直同步时,可能会看到Sync时间很长(例如13.61ms),而关闭垂直同步后,这个时间会消失,但可能出现画面撕裂。 另外,引用[1]还提到,在多线程渲染的情况下,我们可以查看渲染线程(Rendering Thread)的状态。在渲染线程中,灰色的部分显示为“Gfx.WaitForGfxCommandsFromMainThread”,表示渲染线程在等待主线程的命令。而蓝色部分为实际渲染操作。但注意,等待垂直同步的时间通常在主线程的Sync部分体现。 具体到垂直同步造成的CPU等待,我们可以关注: - 主线程中的“Gfx.WaitForPresent”:这个指标表示CPU在等待GPU完成上一帧的渲染并发出垂直同步信号的时间。如果这个时间很长,说明CPU在等待垂直同步,导致无法开始下一帧的计算。 因此,检测方法总结如下: 1. 使用Profiler连接真机运行游戏。 2. 在CPU Usage模块中,查看主线程的时间线,注意“Gfx.WaitForPresent”项的时间。 3. 同时,观察整个帧的时间分布,特别是Sync部分的时间。 注意:如果“Gfx.WaitForPresent”时间较长,且帧率被限制在屏幕刷新率(如60Hz,即每帧16.67ms)附近,那么很可能是垂直同步导致的等待。 另外,引用[3]中提到了协程和线程的区别,但与本问题关系不大。引用[4]提到了避免使用tag比较来减少GC,但也不直接相关。 所以,检测垂直同步造成的CPU等待,核心就是通过Profiler查看主线程中的“Gfx.WaitForPresent”时间。 下面,我们按照要求生成相关问题。</think>### Unity 中检测垂直同步导致的 CPU 等待方法 #### 核心检测工具:Unity Profiler 1. **开启深度性能分析** - 打包时开启开发模式:`Build Settings > Development Build` - 启用自动连接分析器:`Player Settings > Script Debugging + Profiler Support` - 移动端需在设备设置中启用 USB 调试(Android)或开发者模式(iOS) 2. **关键性能指标定位** ```mermaid graph LR A[Profiler CPU模块] --> B[主线程时间线] B --> C{查找Gfx.WaitForPresent} C -->|高耗时| D[垂直同步等待] C -->|低耗时| E[无显著等待] ``` - **Gfx.WaitForPresent**:直接显示 CPU 等待垂直同步信号的时间 - **Sync 区域耗时**:引用[1]中示例显示同步占用 13.61ms(占总帧时间 81%) - **渲染线程状态**:观察灰色区域 `Gfx.WaitForGfxCommandsFromMainThread` 3. **操作步骤详解** 1. 打开 Profiler:`Window > Analysis > Profiler` 2. 选择 CPU 模块,切换至 Hierarchy 视图 3. 在时间线选择目标帧 4. 检查主线程中各部分耗时: - **脚本逻辑**(绿色区域) - **渲染处理**(红色区域) - **同步等待**(蓝色区域) 5. 重点关注 `Gfx.WaitForPresent` 项的时间值 #### 诊断验证方法 1. **对比测试**: ```csharp // 测试脚本:切换垂直同步状态 void Update() { if (Input.GetKeyDown(KeyCode.V)) { QualitySettings.vSyncCount = (QualitySettings.vSyncCount == 0) ? 1 : 0; } } ``` - 开启 VSync 时:Sync 区域显著增加(如引用[1]中 13.61ms) - 关闭 VSync 时:Sync 区域消失,帧时间≈真实渲染时间 2. **性能数据解读**: - 安全阈值:`Gfx.WaitForPresent > 2ms` 需优化 - 危险信号:Sync 时间 > 帧时间 50%(如 60fps 帧中 >8ms) - 典型问题帧特征: - 总帧时间 ≈ 屏幕刷新周期(如 16.67ms@60Hz) - 实际渲染时间 << 总帧时间(如渲染 3ms + 等待 13ms) #### 优化分析建议 1. **关联指标监控**: - GPU 模块中的 `Present.Delay` - 渲染线程中的批次提交耗时 - 内存模块的 GC 分配(引用[4]提到 tag 比较产生 180B GC) 2. **高级诊断工具**: - Unity Frame Debugger:分析具体渲染指令 - Android GPU Inspector(AGI):硬件级 GPU 分析 - Xcode Instruments(iOS):Metal 性能分析 > **诊断结论示例**: > 当观察到 `Gfx.WaitForPresent` 持续高位(如 >10ms)且实际渲染时间较低时,可确认垂直同步导致 CPU 空闲等待。此时应优化渲染性能或调整帧率策略(引用[1]案例中关闭 VSync 后等待时间归零)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值