使用垂直同步时,可接受的时序策略是什么?

时间:2013-04-12 11:31:11

标签: opengl graphics 3d vsync

基于对OpenGL编程的基本理解,所有必需的绘图操作都按顺序执行,每帧重绘一次。硬件的性能决定了这种情况发生的速度。据我所知,游戏将尝试尽快绘制,因此重绘操作基本上包含在while循环中。然后将优化图形操作(图形引擎)以确保应用程序可接受帧速率。

支持垂直同步的图形硬件会将帧速率锁定到显示速率。第一个问题是图形引擎应该如何与硬件同步交互?这是否可行,或者渲染器是否以最大速度工作,硬件有选择地调用最新帧,丢弃所有未使用的先前帧..?

这个问题的动机并不是我立即打算编写图形引擎,而是调试现有系统的问题,其中移动场景的图形看起来在屏幕上断断续续。对称地说,当VSync关闭时,口吃很轻微,当它打开时,有明显的周期性口吃,或者口吃被完全解决。我有点紧紧抓着发生了什么或为什么,想要了解更多有关图形系统的背景信息。

总的来说,问题是如何期望与硬件重绘事件进行交互,如果可能的话。但是欢迎任何其他信息。

2 个答案:

答案 0 :(得分:1)

  

第一个问题是图形引擎应该如何与硬件同步交互?

为了避免闪烁现代渲染系统使用双缓冲,即有两个颜色平面缓冲器,并且在完成绘制到一个之后,显示读出指针被设置为完成的缓冲平面。此缓冲区交换可以同步或非同步。启用V-Sync后,缓冲区交换将同步,渲染线程将阻塞,直到缓冲区交换发生。

由于使用双缓冲强制缓冲交换,这隐含地引入了同步机制。这就是交互式渲染系统锁定显示刷新的方式。

  

症状地说,当VSync关闭时,口吃很轻微,当它打开时,有明显的口吃或周期性口吃,或者口吃完全解决。

这听起来像是一个写得很糟糕的动画循环,它假定帧速率恒定锁定在显示刷新率上,基于帧渲染速度快于显示刷新间隔的假设,并且可以及时发出缓冲区交换以便下一次回扫发生

处理垂直同步的唯一有效方法是实际测量帧渲染之间的时间,并将渲染循环推进一段时间。

答案 1 :(得分:0)

这是猜测,但是:

问题不是垂直同步

我不知道您正在使用哪种操作系统,但有多种方法可以获取有关显示器的信息以及屏幕刷新的速度(为了这个答案的目的,我们假设您的显示器有点最近以60 Hz的速度重绘,或每秒60次,或每16.66666 ......毫秒一次。

渲染器通常与应用程序的“逻辑”端配对:输入,ui计算,模拟运行等。看起来你的应用程序的逻辑方面运行得足够快,但渲染方面 - 即,Draw Call通常总结为 - 正在限制你申请的速度。

垂直同步可能会加剧这种情况,因为如果你的Draw Call每16.66666毫秒发生一次 - 但它需要更长而不是16.666666毫秒 - 那么你会感觉到帧速率下降(即帧将“口吃“因为他们花了太长时间来生产一个框架”。 VSync - 以及它的启用或禁用 - 不会使你的代码陷入困境:它只是说“嘿,因为硬件每16.666666毫秒才会从我们这里拿走1帧,为什么每16.66666毫秒只能进行一次绘制调用?只要我们每次通过一次抽奖活动一次,我们的应用程序看起来会尽可能流畅,而且我们不必浪费时间拨打电话!“

问题在于它假设您的代码将足够快地运行以使其在16.6666毫秒内完成。如果没有,口吃,滞后,视觉伪像,冻结帧和其他东西在屏幕上显示出来。

当你关闭VSync时,你会尽可能快地告诉你的渲染调用。这可能会给Logic提供一些额外的摆动空间以获得渲染帧,这样当硬件说“我现在要拍照并把它放在屏幕上!”只是及时地准备好并准备好cheese!(虽然按照你所说的,它几乎没有成功)。

该怎么做:

首先分析您的代码。找出哪些功能花费的时间最多。从口吃来判断,代码中的某些内容比预期的要长,并且会给您带来不良后果。首先确保个人资料找到你正在消磨时间的关键部分,并弄清楚如何保持正确 让它同样快。您可能想要弄清楚渲染调用中调用的内容,并分析完成一个循环所需的时间。然后计算逻辑调用,看看执行它们需要多长时间。然后,砍掉。

祝你好运!