VSync(垂直同步)——一种将 GPU 每个新帧的输出与显示器刷新率同步的技术,消除图像撕裂。根据 Apple Metal Documentation,在移动设备上,与 VBlank 同步对于流畅渲染是必需的。当帧在垂直扫描期间更新时,就会出现 屏幕撕裂,而 VSync 可防止这种混合。
要点
VSync(垂直同步)——一种硬件-软件机制,强制 GPU 在显示新帧之前等待垂直消隐信号(VBlank)。没有 VSync,GPU 可以随时发送帧,即使显示器正在渲染当前帧,这会导致沿水平线的图像撕裂。
在 移动设备 上,VSync 在图形驱动程序和操作系统级别实现。iOS 通过 Metal 使用 VBlank 同步,Android 通过 SurfaceFlinger 和 BufferQueue 实现。启用垂直同步后,应用程序的 FPS 不能超过显示器的刷新率——60、90 或 120 Hz,具体取决于设备型号。
垂直同步 一词源于 CRT 显示器的工作机制,其中电子束从上到下逐行绘制图像。帧完成后,电子束返回到左上角——这一刻称为垂直消隐。现代 LCD 和 OLED 显示器保留了这一术语,尽管物理工作原理不同。
GPU 在后缓冲区中渲染帧,而显示器从前缓冲区读取。VSync 确保缓冲区交换仅在 VBlank 时刻发生——当显示器已完成当前帧的显示并准备好显示下一帧时。这种机制称为通过 VBlank 同步的 双缓冲。
双缓冲 使用两个缓冲区:前缓冲区(显示在屏幕上)和后缓冲区(GPU 将当前帧写入此处)。当帧准备好时,缓冲区交换位置。启用 VSync 后,此交换会延迟到最近的 VBlank。如果帧在 VBlank 之前准备好,GPU 将保持空闲,这会降低性能但消除撕裂。
// OpenGL — 通过 WGL_EXT_swap_control 启用 VSync
HDC hdc = wglGetCurrentDC();
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT =
reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(
wglGetProcAddress("wglSwapIntervalEXT"));
wglSwapIntervalEXT(1); // 1 = VSync 启用,0 = 禁用
VBlank — 当前帧的最后一行与下一帧的第一行之间的短时间间隔。此时,显示器不会更新像素,缓冲区交换不会产生伪影。VBlank 的持续时间取决于刷新率:在 1080p 显示器上以 60 Hz 运行时,VBlank 持续约 1.4 ms。如果 GPU 未能在 VBlank 之前完成渲染,则该帧将被跳过,显示器再显示前一帧一个周期——这会被感知为卡顿(stutter)。
三缓冲 通过添加第三个缓冲区解决了 GPU 空闲的问题。即使其中一个后缓冲区正在等待 VBlank,GPU 也可以立即开始渲染下一帧。这提高了 VSync 下的 FPS,但增加了一个额外的帧延迟。在移动设备上,三缓冲用于某些游戏引擎和 Vulkan 的 Mailbox 模式中。
关闭 VSync 可提供最大 FPS 和最小输入延迟,但代价是视觉伪影。对于移动游戏和具有流畅动画的应用程序,在 VSync 和关闭它之间的选择是图像清晰度和控制响应性之间的折衷。
屏幕撕裂——一种水平撕裂,其中屏幕的上半部分显示前一帧,而下半部分已经显示下一帧。当 GPU 在显示器扫描周期的中间交换缓冲区时,就会发生这种情况。在移动设备上,快速滚动或高帧率的动态场景中,撕裂尤其明显。具有即时响应的 OLED 显示器 使撕裂与 LCD 相比更具对比度。
撕裂的强度取决于 FPS 与刷新率的比率。在 60 Hz 屏幕上以 60 FPS 运行时,撕裂表现为一条静态线,而在 60 Hz 上以 300 FPS 运行时,则表现为从上到下移动的多条波浪状撕裂。FPS 相对于刷新率越高,撕裂越多,且越明显。
输入延迟 VSync——按下按钮与在屏幕上显示结果之间的延迟。垂直同步平均增加一帧延迟(60 Hz 下为 16.7 ms),三缓冲时则最多增加两帧。对于休闲应用程序,这种延迟是注意不到的,但对于射击游戏、格斗游戏和节奏游戏来说,这是关键的:专业人士甚至能察觉到 8 ms 的延迟。
根据 NVIDIA(2024) 的研究,CS:GO 中 60 FPS 时无 VSync 的平均输入延迟为 22 ms,有 VSync 时为 39 ms。在 144 FPS 时,差异分别减少到 14 和 18 ms。在移动平台上,VSync 的输入延迟不那么关键,因为触摸输入的触控屏硬件延迟(10–30 ms)掩盖了额外的同步延迟。
在 移动开发 中,VSync 通过图形 API、游戏引擎和操作系统系统设置进行管理。iOS 提供的控制较少,Android 通过 Vulkan 和 OpenGL ES 提供更多控制。模式的选择取决于应用程序类型:游戏、UI 或视频。
Unity 使用 QualitySettings.vSyncCount 设置:0 — 关闭,1 — 每个 VBlank 时 VSync,2 — 每隔一个(FPS 减半)。在 Unreal Engine 中,VSync 通过控制台命令 r.VSync 和 DefaultEngine.ini 进行管理。对于移动版本,建议在 Unity 中关闭 VSync 并使用自己的 FPS 限制器,因为 Android SurfaceFlinger 中的内置 VSync 可能会产生不可预测的延迟。
// Unity — VSync 和 FPS 管理
void Awake()
{
// 0 = VSync 禁用,1 = VSync 启用
QualitySettings.vSyncCount = 0;
// 用自定义 FPS 限制器替代 VSync
Application.targetFrameRate = 60;
}
Vulkan 通过 VkSwapchainPresentInfo 和 presentMode 提供完全控制:VK_PRESENT_MODE_FIFO_KHR — 经典 VSync,VK_PRESENT_MODE_MAILBOX_KHR — 无需等待的三缓冲,VK_PRESENT_MODE_IMMEDIATE_KHR — 无同步。iOS 中的 Metal 通过 CAMetalLayer.displaySyncEnabled 管理 VSync。从 iOS 14 开始,Apple 建议默认对所有应用程序使用 displaySyncEnabled = true,但带有街机控制的游戏除外。
| 模式 | 描述 | 延迟 |
|---|---|---|
| FIFO | 带 VBlank 等待的经典 VSync | 1 帧 |
| Mailbox | 三缓冲,丢弃旧帧 | 1–2 帧 |
| Immediate | 无同步,最大 FPS | 0 帧 |
FPS 限制器——VSync 的替代方案,应用程序通过编程方式限制帧率,而无需等待 VBlank。这种方法提供可预测的延迟,并且不依赖于显示器的刷新率。在 Android 上,FPS 限制通过 Choreographer 实现,在 iOS 上——通过 CADisplayLink 手动控制输出时间实现。
传统 VSync 有一个根本性缺点:它依赖于固定的显示器刷新率。如果 GPU 在 60 Hz 屏幕上产生 45 FPS,VSync 无法显示 45 帧——它会显示 30(跳过每个第二个 VBlank)或以不均匀的间隔在 60 和 30 之间交替。这会产生卡顿(stutter),这比撕裂更破坏游戏体验。
自适应同步(FreeSync、G-Sync、Apple ProMotion)通过根据应用程序的 FPS 动态改变显示器刷新率来解决这个问题。如果应用程序产生 47 FPS,显示器切换到 47 Hz——每帧精确显示一次,没有撕裂和卡顿。iOS 中的 ProMotion 自动选择 24 到 120 Hz 的频率,平衡流畅度和功耗。
在移动设备上,自适应同步正在成为标准:配备 ProMotion 的 iPad Pro(2017+)、配备 LTPO 显示屏的 Android 旗舰手机(Samsung Galaxy S23 Ultra、Google Pixel 8 Pro)支持 1 到 120 Hz 的动态刷新率。对于开发人员来说,这意味着传统意义上的 VSync 被系统管理取代——只需设置 targetFrameRate,操作系统就会自动调整刷新率,以实现流畅度和电池续航时间的最佳平衡。
常见问题
不需要。在动态游戏(射击游戏、格斗游戏)中,VSync 会增加输入延迟而没有显著好处——由于显示器尺寸较小,移动 OLED 屏幕上的撕裂不太明显。对于休闲游戏和 UI,VSync 可改善流畅度的感知。
VSync 降低功耗,因为 GPU 不会渲染多余的帧。关闭 VSync 时,GPU 以最大频率工作,每个未显示的帧都会浪费能源并使设备发热,对用户没有任何好处。
VSync 将帧输出与显示器的 VBlank 同步,而 FPS 限制器只是限制应用程序代码中的渲染频率。FPS 限制器不能消除撕裂,但提供可预测的延迟,而不依赖于屏幕的刷新率。
当 GPU 未能在 VBlank 之前完成帧时,VBlank 被跳过,该帧将显示两个刷新周期。在 60 Hz 下,这会产生 30 FPS。三缓冲减轻了这种效果,允许 GPU 无需等待即可开始下一帧。
是的。iOS ProMotion(iPad Pro、iPhone 13 Pro+)支持 24–120 Hz 的动态频率。Android 通过 LTPO 面板支持 1–120 Hz。开发人员无需手动管理——系统会自动选择最佳频率。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。