本文已参与「新人创作礼」活动,一起开启掘金创作之路。
什么是垂直同步V-Sync
垂直同步是显卡提供的一个功能,目的是将游戏帧率和显示器的刷新率进行同步。当开启V-Sync后,显卡会等待显示器本轮刷新完成,在这期间,显卡不会向显示器传输任何数据,并且通过双缓冲和页翻转(page flipping)技术确保当显示器刷新完成后获得下一帧的画面。
为什么需要V-Sync呢?
首先,FPS超过刷新率并不能提高实际感受到的帧率。因为你看到画面是最终要通过显示器的刷新来变化。比如显示器的刷新率是60Hz,那么如果游戏以120FPS的帧率渲染,实际上每渲染两帧才有一次更新显示器画面的机会,那么前一帧的渲染就浪费了,你只能看到第二帧渲染后的结果。当然这不是说FPS超过刷新率就一定没意义,更高的FPS带来更精细的计算和更高精度的输入处理。实际上,更重要的原因是,如果没有垂直同步,当FPS特别高时,显示器有可能在未刷新完成当前帧时,接受到一帧新的数据,那么就有可能在一次刷新过程中,同时显示两个不同的帧,当这两帧画面差异较大时(例如快速的移动镜头),就会产生明显的画面撕裂现象,体验很不好。而使用V-Sync则可以避免这种现象产生。
- 当帧率高于刷新率时,关闭V-Sync会产生画面撕裂
FPS低于刷新率时,V-Sync的问题
当然并不是打开V-Sync就万事大吉了。V-Sync不仅仅只是限制FPS,V-Sync做的事情是同步,即在合适的时候接受显卡发送来的画面。而当FPS低于刷新率时,有可能当显示器完成本轮刷新时,显卡还没渲染好下一帧画面。例如当前显示器刷新率为60Hz,即每次刷新之间的间隔约为16毫秒。假设当前游戏FPS为20FPS,即每50毫秒能渲染一帧。那么第16毫秒时,游戏还没有帧被渲染出来,本次同步无效(具体细节可能没那么简单),第20毫秒时第一帧被渲染出来放到帧缓冲区中,但此时没有到显示器的刷新周期,因此显卡只能等待。第32毫秒时,显示器刷新周期再次到来,帧缓冲区的内容被同步到显示器显示出来。那么实际上,一共花费了32毫秒才显示出一帧画面,实际的FPS为30。当然在第80毫秒时,渲染帧赶上了一次刷新,FPS暂时性的提高到60,但这之后又跟不上节奏,变回了30FPS。以上讨论的只是理想情况,实际情况FPS是变化的,总的来说,低帧率时往往赶不上刷新周期的车,导致实际FPS降低,且降低到刷新周期的倍数对应的FPS。这样,FPS的变化就不是平滑渐变的,而是在例如30和60FPS之间跳变,形成卡顿现象。
- 当FPS低于显示器刷新率时会产生垂直同步卡顿(V-Sync Stutters)
自适应的垂直同步(Adaptive V-Sync)
V-Sync打开时,如果帧率低于刷新率,会导致卡顿;而V-Sync关闭时,如果帧率过高,又会导致画面撕裂。那V-Sync到底应该开还是关呢?nvidia提供了自适应V-Sync功能,可以根据帧率的高低适时的关闭和打开V-Sync。
上图中,当FPS低于60时,自动关闭V-Sync,避免帧率直接卡顿到30。而当FPS高于60时,自动打开V-Sync,避免画面撕裂。
这个功能不错,但这是显卡厂商提供的管理功能,需要用户通过显卡控制软件自己打开。其实完全可以在游戏中自行判断是否要打开或关闭V-Sync。当然必须能在程序中控制V-Sync的开关。对于OpenGL可以使用wglSwapIntervalEXT来控制,DirectX也有相应的方法。