游戏中的“垂直同步”与“三重缓冲”究竟是个啥?

2023-11-10

从今天开始,我们会开启“小教程”的兄弟栏目——小科普,给大家介绍在配电脑或玩游戏过程中经常会遇到的专业名词。

第一期“小科普”我们来讲讲游戏中经常会遇到的一个画面选项——垂直同步

我们曾在一期语音里和大家讲探讨过垂直同步的功用,可惜语音有 60 秒的长度限制,并不能和大家解释清楚,那么今天就来详细分析一下“垂直同步”:

  • 它到底是干嘛用的?

  • 它有什么缺点吗?

  • 和它搭档的“三重缓冲”又是个啥?

以及最重要的一点:我在游戏中到底该不该开启它?

(本文中的部分内容参考自外媒 Anandtech 的技术文章,我们将在文末提供其链接)

另外,本文阅读起来有难度,如果你是抱着太长不看的心态阅读,建议直接看最后的结论 。

垂直同步是干嘛的?

要想解答这个问题,首先得来说说“垂直同步”所解决的问题——画面撕裂。当我们在玩游戏的时候,有没有遇到下图这种情况呢:

一帧画面被分割开了,这种情况便是“画面撕裂”。

不过你可能会说,我用的可是高端显卡呀,为什么还会出现这种问题呢?

你还别说,越是高端的显卡,跑到的帧数越高,还就越容易出现这种问题。

这里就要说说说画面撕裂产生的原因了。为了方便各位理解,我们先来简单说说显卡与显示器之间是如何工作的:

可以看到,显存中的“帧缓冲区”(Framebuffer)是图像传输的一个关键区域,显卡所生成的一帧画面会先被写入帧缓冲区。而一台 60Hz 的显示器每秒能够显示 60 幅画面,也就是说每 1/60 秒(当显示器刷新完一幅画面时)会给显卡发送一次“垂直同步信号“,向帧缓冲区索取一次画面数据,然后显示出来。

不过光有一个帧缓冲区会产生一个问题,这一个缓冲区会不断地写入新的画面并发送给显示器,这样一来“写入的全过程”就会被展现在屏幕上了,这就会导致画面闪烁等问题。因此,现代的图形工作流程中使用的多是双重缓冲:

双重缓冲有一前一后两个缓冲区,显卡只会将绘制完的图像写入后缓冲区,与此同时只有前缓冲区中的图像会被发送给显示器。

当后缓冲区中的“新鲜”图像写入完成后,注意啦,程序不会将后缓冲区的画面传输到前缓冲区,而是会进行缓冲区的交换(Swap)——将前缓冲区和后缓冲区的名字对调,即前缓冲区成了后缓冲区,后缓冲区成了前缓冲区。这样以后,刚刚绘制在后缓冲区的图像就能顺利地传给显示器了。经过这么一折腾,程序就可以在往后缓冲区写入图像的同时,不影响显卡将前缓冲区中的画面传给显示器,然后进行下一次“缓冲区交换”。

但是双重缓冲有个问题,两个缓冲区随时都可能发生交换,所以就会出现这种情况:前缓冲区中的画面才刚传输了一半给显示器,两个缓冲区就发生交换了,后面传输的都是原来后缓冲区中的画面(即下一帧画面)。于是,显示器上的一幅画面成了前后两帧的结合,这就是画面撕裂。这种问题在高帧率情况下尤为显著,因为帧率越高,前后缓冲区的交换就越为频繁,发生这种事件(画面没输出完就交换了)的概率自然也就更高。

-哇,原来画面撕裂是这么来的啊!那有没有什么办法能解决它呢?

-当然有了,那就是“垂直同步”选项。

(PS:“垂直同步”是一种简写,完整的称呼应是“等待垂直同步信号”)

开启垂直同步,就相当于在帧缓冲区里架设了红绿灯。当显示器尚未完成一帧画面的刷新时,红灯亮起,两个缓冲区不允许交换;当显示器刷新完一帧画面时,绿灯亮起,此时缓冲区可以进行交换了。这样以后就杜绝了“在进行数据传输的过程中交换缓冲区“的可能,自然也就解决了画面撕裂的问题。

不过为啥这个功能要叫“垂直同步”呢?这是因为在 CRT 大屁股显示器的年代,显示器的刷新是逐行或隔行刷新的,电子枪一行一行地打下去,打完每一行就称这一行完成了“水平同步”,打到最后一行的最后一个像素点就完成了一帧画面的显示,然后显示器会给显卡发送“垂直同步信号”,表明垂直向的像素点也完成了同步,即这一帧刷新完成了。

哇,垂直同步这么好,那我现在就去游戏里打开它,如何?

别急,“垂直同步”虽然能彻底杜绝画面撕裂,但是它的副作用同样很明显——操作延迟。

在帧率比显示器刷新率高很多的情况下,为了将显示器的刷新时间和显卡向缓冲区写入画面的时间保持同步,必然就需要人为地增加延迟,来延后“过快生成的画面“向显示器的输出。因此在竞技游戏中,开启垂直同步后的手感会大打折扣。

这里用一个实例来作说明:

这是未开启垂直同步时,传统双重缓冲下的图像,由于 300fps 的高帧率,每两个“垂直同步信号“之间会生成高达 5 幅画面,这就导致了严重的画面撕裂。

这是开启了垂直同步后的图像,可以看得出画面撕裂的问题确实得到了解决,但为了将帧缓存交换的时间和显示器刷新时间保持同步,帧缓存中的画面将会延后一个刷新周期被显示出来。在使用 60Hz 显示器时,一个刷新周期的时间高达 16.67ms,也就是说本来一秒五帧的图像延迟只有 3.3ms,现在因为要干等一个刷新周期,延迟一下子就增加到了 13.3ms,对于连 5ms 和 1ms 显示器都能分清的电竞选手而言,这多出来的10毫秒延迟是非常要命的。

哎呀,不开垂直同步会画面撕裂,开了又会有延迟,那画质和性能就不能兼得吗?

能啊,要想画质与操作兼得,有两个办法

第一个办法,买个 G-SYNC 或 FreeSync 的电竞显示器

这些显示器可以动态调整自己的刷新率,使其和显卡输出画面的帧率完全同步,这样不仅可以在解决画面撕裂的同时不出现操作延迟,还可以在帧率低于 60fps 的情况下同样提供垂直同步的效果,消除画面撕裂。不过,这毕竟是个要花大钱的办法,而且据我所知,几乎没有哪个电竞屏的屏幕素质是很优秀的,为了达到低延迟,许多电竞屏都采用了 TN 面板,对于电竞选手而言当然无可厚非,但对我这样的画面党来说,这样的屏幕看起来就有点难以接受了。

第二个办法,相信大家已经猜到了:三重缓冲!

既然垂直同步的延迟是因为显卡输出完一幅图像就歇着等待红绿灯了,无法响应鼠标键盘最新的操作,那么我们为啥不让显卡一直工作呢?这样不就能一直响应最新的输入操作了吗?三重缓冲就是基于这种思路设计的,它在双重缓冲的基础上再加入了一个帧缓冲区,组成了一个前缓冲区,两个后缓冲区的规格。程序来回向两个后缓冲区写入图像,每次显示器刷新时,前缓冲区就和最近完成写入的那个后缓冲区交换。可以看到,即便有一个缓冲区要受到红绿灯的管控,另外两个缓冲区还是可以来回写入图像,于是就不需要人为增加画面延迟了。

这张图便说明了三重缓冲的原理,这种方法结合了前两种的优点。

不过三重缓冲也并非完美无瑕。首先由于需要一个额外的帧缓冲区,因此它会占用更多的显存空间。比如我们在 4K 分辨率下运行《质量效应:仙女座》,三重缓冲额外占用了约 200MB 的显存,对我们而言尚可接受。其次,它的延迟虽然远远低于双重缓冲下的垂直同步,但相比不开垂直同步还是可能略微高一点,因为无垂直同步的画面在给你带来撕裂的同时,也会包含最新帧的图像,如果开启了三重缓冲,那么画面中这“后面一帧“的多余元素就会被剔除,延迟自然会略微高于前者一点点。不过和满屏的画面撕裂相比,我显然还是会选择三重缓冲的……

看到这里,你肯定迫不及待地想要开启三重缓冲了吧,的确,垂直同步+三重缓冲是种非常棒的技术,可以有效地改善画面撕裂,同时不造成画面延迟。但是问题来了,DirectX 并不原生支持三重缓冲!而是使用了一种叫“预渲染队列“的方式。这种方式与三重缓冲不同的地方在于,它不会丢弃显卡渲染完却未被使用的帧(即过时的帧),而会强制将这些旧帧显示出来,因此会造成更大的操作延迟,甚至比光开垂直同步的延迟还要大。DirectX 的游戏若想使用三重缓冲,需要游戏厂商提供相应的支持。

很可惜的是,不少采用 DX API 游戏虽然在画面选项里提供了”三重缓冲“选项,实际上却是使用了“包含 3 个缓存空间的预渲染队列”,这些游戏使用的到底是不是真正的三重缓冲,只有你亲身体验后才能弄明白。所以,能不能开启三重缓冲,还要看游戏厂商的心情啊!

总结:

垂直同步和三重缓冲到底该不该开呢?如果游戏支持,条件允许的话(对于 60Hz 显示器的用户,显卡能跑到 60 帧以上),还是尽量开起来试试。但如果你的显卡达不到这么高的速度,或者你经过试验发现某一款游戏在三重缓冲下的操作延迟依然很高,那还是把它关了吧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

游戏中的“垂直同步”与“三重缓冲”究竟是个啥? 的相关文章

  • D3D纹理

    纹理映射是一种将图形施加到表面的技术 以简单的一堵墙为例 这种技术可以只需要两个绘制有砖纹理的三角形即可 这样就可以为表面增加大量的细节 而不必使用大量的多边形 纹理映射使用了图像数据并将图像数据绘制 映射 到表面上 该表面看上去就像有一幅
  • 码农干货系列【1】--方向包围盒(OBB)碰撞检测

    码农干货系列 1 方向包围盒 OBB 碰撞检测 2012 06 07 11 40 by 当耐特 9251 阅读 20 评论 收藏 编辑 干货 最近一直在删文章 不是要关博洗手什么的 而是被删的文章没有达到 干货 的标准 干货的反义词是水货
  • Direct3D VertexBuffer Lock() and Unlock() function

    Stack Overflow is a question and answer site for professional and enthusiast programmers It s 100 free no registration r
  • d3d制作场景地形

    一般可以先用d3d做地形的mesh 比如做一个100 100的网格 然后用photoshop做高度图 然后再程序里读取高度图数据 让mesh的每个顶点对应一个高度 http download csdn net source 855296 这
  • D3D资源管理

    摘要 受管贴图 Managed textures 也就是我们通常所谓的 自动管理贴图 在DX6中首次被引入 经过一系列的改进和增强 在DX9中自动管理的资源类型增加到贴图 顶点缓冲 顶点索引缓冲 所有这些资源使用统一的公共接口 通过使用D3
  • 成功编译RenderingPluginExample53的cpp项目的步骤

    备忘 unity中调用d3d功能的示例项目 两个方面的配置 1 为了在项目中能够找到d3d12 h d3d11 h d3d9 h等 做如下操作 在项目属性中 VC 目录 包含目录 中添加 C Program Files x86 Window
  • 3D MAX导出插件编写

    转 3D MAX导出插件编写 2011 6 9阅读1667 评论0 文章版权归博客园 BigCoder所有 转载请于明显位置标明原文作者及出处 以示尊重 原文出处 http www cnblogs com csyisong archive
  • 高级纹理映射技术(6)

    高级纹理映射技术 6 对一些特殊的应用需要对纹理坐标进行处理 主要包括纹理坐标自动生成和纹理坐标变换 下图显示了纹理坐标的来源 处理过程以及到达光栅处理器的过程 纹理坐标自动生成 在Direct3D程序中 不仅可以在模型载入阶段或渲染阶段指
  • orge工具

    tortoisehg 3 2 1 x64 msi mercurial 3 2 1 x64 msi
  • win10 graphedit存储的路径

    如果安装郭windows SDK的话 可能的存储位置为C Program Files x86 Windows Kits 10 bin x86 C Program Files x86 Windows Kits 10 bin x64
  • fvf采用另外一种方式渲染

    if FAILED hr getActiveD3D9Device gt SetVertexDeclaration d3ddecl gt getD3DVertexDeclaration getGlobalInstanceVertexBuffe
  • 使用GDI/GDI+绘制到D3D9缓冲区的方法

    这个其实是3D绘图里嵌入2D绘图的传统方式 D3D9直接使用GDI GDI 就可以画图 只不过需要额外的设置 而且只支持RGB和XRGB 不支持ARGB 因此这种方法比较适合合成UI元素和不透明的纹理贴图 不适合将要进行AlphaBlend
  • Ogre:Hardwarebuffer

    Ogre Hardwarebuffer 分类 OGRE 2012 07 03 15 56 1097人阅读 评论 0 收藏 举报 buffer float byte 存储 图形 upload Ogre中的硬件缓存是指在显卡上的存储 这和在内存
  • 游戏中的“垂直同步”与“三重缓冲”究竟是个啥?

    从今天开始 我们会开启 小教程 的兄弟栏目 小科普 给大家介绍在配电脑或玩游戏过程中经常会遇到的专业名词 第一期 小科普 我们来讲讲游戏中经常会遇到的一个画面选项 垂直同步 我们曾在一期语音里和大家讲探讨过垂直同步的功用 可惜语音有 60
  • D3D9Texture::_loadNormTex

    D3D9Texture loadNormTex D3D9Texture loadImpl
  • GT1030和730哪个好?GT1030与GT730区别对比 (全文)

    对于显卡硬件厂商来说 当属NVIDIA可谓异常活跃 我们知道在游戏领域 N卡一直占据着绝大部分市场 旗下的显卡定位也非常明确 如最新的10系显卡 今年5月份NVIDIA低调发布了定位入门级显卡 GT1030 这款显卡上市之后立马引起了不少玩
  • 关于visual studio中的$(ConfigurationName)疑问

    关于visual studio中的 ConfigurationName 疑问 2012 12 02 16 09 15 转载 标签 it 分类 程序员之路 关于vs中的各种路径的值de查看方法 来源 http social msdn micr
  • 垂直同步到底要不要开?老司机教你G-Sync显示器的正确打开姿势

    一直以来我们都认为PC的画面效果取决于显卡 认为游戏的FPS值越高代表游戏越流畅 但实际上 显示器也是决定游戏帧数的重要一环 显卡将画面渲染并输出到显示器中 显示器接收GPU的信号并输出 然而 因为显卡性能和运行程序的差异 显卡一般无法以恒
  • Texture::getSourceFileType()

    Texture getSourceFileType
  • cocos2d-x 卡牌翻牌效果的实现

    cocos2d x 卡牌翻牌效果的实现 2012年07月25日 综合 共 3085字 字号 小 中 大 评论关闭 猴子原创 欢迎转载 转载请注明 转载自Cocos2D开发网 Cocos2Dev com 谢谢 原文地址 http www co

随机推荐

  • tcp tw_cycle和tcp_timestamp

    在TCP可选项字段中为TCP预留有时间戳功能 1 TCP可选项格式 kind 1字节 length 1字节 info tcp 选项格式 1 tcp报文格式 由tcp 首部和tcp数据组成 2 tcp首部 由20字节的固定长度和可变长字段组成
  • Python 将不同尺寸的图片和xml标签等比例缩放到指定大小

    Python 将不同尺寸的图片和xml标签等比例缩放到指定大小 xml文件格式 import os import cv2 import numpy as np import xml etree ElementTree as ET path
  • oracle 中的null

    关于null的讨论 http www itpub net thread 932786 1 1 html
  • java并发编程笔记(三)--管程(五)

    8 活跃度 死锁发生的条件 定位死锁的方法 死锁的典型问题 哲学家问题 我们检测下死锁 就比如 我们把随后一个哲学家阿基米德拿筷子的顺序更改 就不会发生死锁 变成 new Philosopher 阿基米德 c5 c1 start 但是这种解
  • 上下文切换理解以及减少方法

    并发编程面临着上下文切换 死锁等问题 尤其在少量数据的情况下 并发可能因为线程的创建和上下文切换的开销等问题 甚至比串行执行的速度更慢 文章目录 上下文切换定义 例子理解 减少上下文切换的方法 无锁并发编程 CAS算法 使用最少线程 协程
  • 【java毕业设计】基于B/S结构+mysql的二手车交易网站设计与实现(程序源码)-二手车交易网站

    基于B S结构 mysql的二手车交易网站设计与实现 程序源码 毕业论文 大家好 今天给大家介绍基于B S结构 mysql的二手车交易网站设计与实现 本论文只截取部分文章重点 文章末尾附有本毕业设计完整源码及论文的获取方式 更多毕业设计源码
  • Vim常用指令

    1 复制 yank 选中的区域并粘贴 put 到另一个区域 在 Vim 中 复制和粘贴被称为 yank 和 put 以下是如何复制 yank 选中的区域并粘贴 put 到另一个区域的步骤 进入可视模式并选择文本 按 v 进入字符可视模式 然
  • 网络类型整理,看你知道几种网络

    目录 无线网络 有线网络 局域网 LAN 城域网 MAN 广域网 WAN 互联网 internet 注意是小写开头 因特网 Internet 注意是大小开头 万维网 WWW 互联网 因特网 万维网是什么关系 我昨天看计算机网络知识的时候 看
  • Map的四种常用实现类的区别

    Map的四种常用实现类的区别 在Java学习中 Map接口主要用四种实现类 分别是HashMap Hashtable linkedHashMap ConcurrentHashMap 这篇文章就来讲讲这四类的区别 HashMap 这是平时使用
  • java 日期转换时间戳_java 日期转时间戳,时间戳转为日期

    package date import java text ParseException import java text SimpleDateFormat import java util Date public class test p
  • JS 事件冒泡和事件捕获

    原文 https www cnblogs com qq9694526 p 5653728 html JS 事件冒泡和事件捕获 本文中关于事件冒泡和事件捕获的描述和例子都是OK的 错就错在后面用jquery去展示了利用事件冒泡的例子有误 其实
  • 常用的快速数学函数(with SSE2 )

    很明显 在工业或者一些智能设备的控制方面 对运行速度的要求总是比较严苛的 有时候 在速度和精度上做一合理的取舍就显得尤为重要了 今天当一个搬运工 带来一些常用的数学库函数 这些函数采用一定的算法对结果进行了高精度的逼近 在工程上应用问题不大
  • Geoserver+mysql+openlayers2

    Geoserver mysql openlayers2 mysql几何数据数据存储参考 DROP TABLE IF EXISTS points CREATE TABLE points id int 11 UNSIGNED NOT NULL
  • AD画PCB,批量修改线宽

    Altium PCB中更改线宽的技巧总结 1 设置altium designer的默认pcb线宽 在布线前直接在设计规则中设置 Design Rules Routing Width 修改这个里面的Preferred Width即可 还可以进
  • [Andrioid开发] Splash界面/用户协议与隐私政策弹窗/界面开发

    Andrioid开发 Splash界面 用户协议与隐私政策弹窗 界面开发 启动页界面开发 首次启动时的启动页用户协议与隐私政策弹窗 只要不点击同意每次打开都会显示弹窗 同意后立即跳转到主界面 当下次再进入软件就是两秒后自动跳转到主界面 实现
  • 建设面向青少年的创客教育实验室

    创客教育的核心是所有学生都是创造者 与为了测试而去记忆知识 创客教育鼓励学生使用他们所知道的去设计和建造项目 这些项目五花八门 可能有黑客 日常物品 音乐编程或使用3D打印机为孩子建立机械假肢 在常规课程中 基础知识部分包括知识背景 项目实
  • Skulpt在线模拟运行Python工具

    1 Skulpt是一个完全依靠浏览器端模拟实现Python运行的工具 2 不需要预处理 插件或服务器端支持 只需编写python并重新载入即可 3 由于代码完全是在浏览器中运行的 所以不必担心 服务器崩溃 问题 github https g
  • Jupyter中使用Pyecharts绘制地图

    背景 根据各省频率绘制地图 根据各省频率绘制地图 可以使用 Pyecharts 绘制 下面是详细的步骤 1 安装 Pyecharts 可以通过 pip install pyecharts 命令安装 2 导入相关库 import pandas
  • Java线程异步执行多个方法

    https jingyan baidu com article 20095761feaa9fcb0721b4d2 html
  • 游戏中的“垂直同步”与“三重缓冲”究竟是个啥?

    从今天开始 我们会开启 小教程 的兄弟栏目 小科普 给大家介绍在配电脑或玩游戏过程中经常会遇到的专业名词 第一期 小科普 我们来讲讲游戏中经常会遇到的一个画面选项 垂直同步 我们曾在一期语音里和大家讲探讨过垂直同步的功用 可惜语音有 60