zoukankan      html  css  js  c++  java
  • 什么是VSync

    VSync是垂直同期(Vertical Synchronization)的简称。主要的思路是将你的FPS和显示器的刷新率同期起来。其目的是避免一种称之为"撕裂"的现象。再以下我将具体介绍这些内容。


    每一台CRT显示器都有自己的刷新率。其单位是HZ.其数值是显示器每秒钟更新画面的次数。不同的显示器支持再不同分辨率下的不同刷新率。它的范围能够从低到60高到100。注意它不是你游戏中所提到的那个FPS.假设你设置了一个特定的刷新率,显示器将一直依照这个速率刷新画面。甚至画面没有不论什么的改变。液晶显示器就不同了。LCD的每一个像素在被告知改变的时候将一直是亮着的。他们不须要刷新。可是由于VGA(或是DVI)的工作原理,LCD不得不从显示卡那里按一定的速率得到新的新画面。这就是尽管LCD不必要更新,可是他还是有自己的刷新率。


    我想这里的每一人都明确FPS。它显示显示卡在每秒钟能够描画多少画面。这显然是越高越好。可是对于高速变化的游戏而言,你的FPS非常难一直保持相同的数值,他会随着你所示显示卡所要描画的画面的复杂程度而变化。这样画面的撕裂就发生了。
    所谓"撕裂"就是一种画面分离的现象,就象你照一张照片,在旋转哪怕一度再照一张照片,然后把两张照片的从中间裁开,用一张照片的上半部与还有一张的下半部对接起来。这样得到的画像尽管相似可是上半部和下半部确实明显的不同。这就被称之为视觉现实上的撕裂。它不会一直从中间分开,它可能靠近上面也可能以下,分离点可能在屏幕上下移动,也可能在两点间前后移动。(译者:原文的作者实在是啰嗦,事实上就是画面移动较快的时候,画面看上去是两截。这样的现象恐怕打游戏的都看到过)。
    为什么会发生这样的现象呢?让我们举一个特定的样例。让我们假定你的显示器的刷新率是75Hz, 你真在玩你最喜欢的游戏,并且你如今有100的FPS.这就意味着你的显示器每秒更新75次画面,而你的显示卡每秒更新100次,比你的显示器快33%。这就意味着在你的显示器更新画面的时间里,显示卡描画了1+1/3的画面。这样在画面显示的时候,那个1/3的画面就会覆盖那个完整画面上部的1/3。在下次的图像刷新的时候,显示卡会描画剩下来得2/3和新的2/3的画面。这样,由于屏幕的更新仅仅能跟上画面更新的2/3,这样图像的上部的1/3或是下部的1/3就会和剩下的画面合不上。假设画面的变化不大可能不太会注意到这一点,可是假设你高速的环顾四周那就会很的明显。

    如今,一个非常普遍的误解就产生了。一些人觉得解决问题的方法就是简单设置一个FPS的限制让FPS不超过显示器的刷新率,这样显示卡就不会超过75FPS,这样就能够了。真的吗?错!


    在我解释为什么之前,让我来讲一下双倍缓冲。双倍缓冲一种用来减轻撕裂问题,尽管不是非常全然。基本上来说你有一个显示缓冲和一个后备缓冲。当显示器要显示画面的时候,就会从显示缓冲里“推出”显示画面。显示卡则在后备缓冲里描画另外一个新画面,当描画完毕后则将新画面考入显示缓冲里。可是这个过程须要时间,假设显示器的刷新在拷贝过程中进行的话,显示器上显示的仍然是个"撕裂"的画面。


    VSync 通过建立一个不让在显示器刷新前将后备缓冲中的画面复制到显示缓冲中的规定来解决问题。假设FPS高于刷新率的话,没有问题。后备缓冲的更新完毕后,系统处于等待状态。当显示器刷新后,后备缓存考入显示缓存,显示卡则能够在后备缓存里描画新的画面,这样就非常有效的将你的FPS限制在显示器的刷新率的范围内。

    这样看起来不错,可是让我们来看一个另外一个不同的样例。让我们假定你已经玩到了你最喜欢的游戏的最后一关,这个游戏有非常好的图像.你显示器的刷新率还是在75。可是你的FPS如今仅仅有50了,比刷新率要低33%.这就意味着每次显示器刷新图像,你的显示卡仅仅能画出下一桢画面的2/3。让我们看看它是怎样工作的。显示器刚刚更新,第一桢的画面已经复制到显示缓冲,第二桢的画面的2/3被写入后备缓冲,这时显示器又一次刷新,它会第一次从显示缓冲里提取第一桢的画面。然后显示卡開始完毕的第二桢剩下的部分。可是它必须等待,应为再下一次刷新之前它是不会上传的。显示器再次刷新,显示器不得不第二次从显示缓冲里提取第一桢的画面,然后第二桢的画面被写入显示缓冲。显示卡在后备缓冲中写入第三桢的2/3.等到显示器刷新,第一次从显示缓冲里提取第二桢的画面,显示卡開始完毕的第三桢剩下的部分。然后又是第二次从显示缓冲里提取第二桢的画面,然后第三桢的画面被写入显示缓冲。如此类推。这样4次显示器刷新,我们仅仅能的到2桢的画面。假设刷新率是75的话,我们仅仅能得到35的FPS.非常明显这个数值要低于显示卡能够带到的50FPS.这主要就是应为显示卡不得不在描画后备缓冲上浪费时间。而在此过程中,后备缓冲上的画面是不能被复制到显示缓冲。理论上讲,双缓冲的VSync,FPS将是一组不连续的整数,其等于刷新率/n,n是正整数。也就是说,假设你的刷新率是60hz,你能得到的FPS仅仅能是 60,30,20,15,12,10 等等。你能够注意到60到30是一个相当大的差距。仅仅要的显示卡的FPS在60到30之间,你说得到的真实FPS都将仅仅能等于30!


    如今,你明确为什么有人不喜欢它了。让我们回到一開始的那个样例。你在玩你最喜欢的游戏,刷新率是75HZ,100FPS。你打开VSync.游戏就被限制在75FPS,没有问题,没有撕裂图像,看起来不错。你到了一个图像特别复杂的地方,在不用VSync的时候,你的FPS下降到了60左右。可是你打开了VSync,你的FPS实际就仅仅有37.5。这样你的游戏突然从75FPS变成了37.5FPS,无论37.5仍然非常流畅可是你一定会注意到刷新率突然降低了一半。当让假设下面变到25FPS的话,实际的现实率可能就仅仅有17.5。本来还能够玩的游戏,就变成了幻灯片。这就是大家不喜欢它的原因。


    假设你的游戏的FPS能够一直稳定的大于显示器的刷新率,VSync是个不错的东西。可是假设FPS忽大忽小。VSync就是让人烦的东西。假设你的游戏FPS一直都小于刷新率的话,实际的FPS要远远小于显示卡能够显示的FPS.看上去就象是VSync减少了你的FPS,可是从技术角度讲,不是应为图像太复杂,而是由于VSync就是这样工作的。
    也不是说全部的希望都没有了。如今的triple-buffering技术能够用来解决问题。让我们再来看刷新率75。FPS50的样例。第一桢在显示缓冲,第二桢的2/3在后备缓冲。显示器刷新第一桢第一次被显示,在后备缓冲里描画第二桢的剩下的1/3,在第二后备缓冲里描画第三桢的1/3(由于我们有三级缓冲了)。显示器再次刷新第一桢第二次被显示,第二桢放入在显示缓冲,第三桢的的1/3放入后备缓冲,第二后备缓冲里描画第三桢剩下的2/3。接下来显示器再次刷新的时候,第二桢被显示,第三桢就能够放入显示缓冲,这样我们就能够在3次刷新中得到2桢的画面。也就是刷新率的2/3,也就是50FPS.triple-buffering理论上讲能够避免缓冲写入是带来的延迟现象,这样就不会浪费时间。可是triple-buffering并非适用于全部的游戏。实际上它并非普及(这个文章可能写的太早,如今triple-buffering已经非常普及了),并且它也会影响显示卡的性能,应为它须要很多其它的显示内存,须要很多其它时间在内存之间降数据拷贝来拷贝去。可是triple-buffering确实是一个非常好的方法,既能够消除撕裂画面又能够不像普通VSync一样影响你的FPS.

    我希望这篇文章是实用的,能够帮出你理解VSync的工作原理。(特别是不再犹豫是否打开VSync)总之,假设没有triple-buffering的情况下,怎样权衡Vsync的FPS限制和消除撕裂画面带来的视觉感受,那将全然取决于你个人的喜好。


    译者按:假设这篇文章的机理是正确的。triple-buffering也不是万能的,实际上就是把降低1/2变成了降低1/3而已,假设是FPS恰好卡到了一定的数值的时候没有问题,一旦没有,那就绝对要损失FPS.所以对于那种FPS刚刚超过24的游戏,无论有没有triple-buffering,都应该关.


    液晶显示器的刷新频率为何不能调高?



     邮件地址为lipi****491@163.com的读者询问:听说显示器的刷新频率越高,屏幕闪烁程度就越小,对眼睛的伤害也就少了,可是我的液晶显示器刷新率为什么仅仅有60Hz,不能像别人那样调高到75Hz或是85Hz呢?

      答:这里有一个误解。



    原来我们使用的是CRT技术的显示器,为保证长时间地注视屏幕而眼睛不疲劳,我们一般都会把刷新率调到75H甚至是85Hz,这是因为CRT技术的特性决定的,刷新率越高也就意味着图像越清楚、越稳定。可是对于LCD来说,因为液晶板本身并不发光,仅仅是液晶分子控制光线的偏转或通过,发光的是背光源,即荧光灯管,在使用的时候即使把刷新率调到60Hz你也不会感到屏幕在闪烁,“刷新率”对LCD来说已经没有多大意义了,所以在使用液晶显示器的时候,我们是不必过于苛求刷新率的高低的。


  • 相关阅读:
    Day5下午解题报告1
    Linux 命令整理
    [置顶] 正则表达式应用:匹配email地址
    IE浏览器下web调试工具之--IE WebDeveloper介绍
    ORACLE客户端乱码
    冒泡排序
    【C++】第二章:Hello World!
    hdu4710
    (SQL SERVER) (ORACLE) (ACCESS)(POSTGRE SQL)四种数据库操作C#代码
    How to calculate the undo_retention time
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3918123.html
Copyright © 2011-2022 走看看