ballance吧 关注:9,741贴子:401,531
  • 8回复贴,共1

(可能是)你想了解的有关 Ballance 窗口化高帧的一切

取消只看楼主收藏回复

1L 喂度娘


IP属地:上海1楼2021-01-31 21:54回复
    1. 什么是窗口化高帧?
    故名思义, 窗口化高帧,即在窗口化模式下使得 Ballance 运行在高帧率(即无限制帧率)的模式下。由于在之前的研究中,尝试各种设置组合,使用各种办法都无法达成窗口化高帧,因此该问题成为了一个困扰广大吧友的一个问题。


    IP属地:上海2楼2021-01-31 21:55
    回复
      2. 解锁原理
      调用 CKTimeManager::ChangeLimitOptions() 来改变 vt 引擎的锁帧方式。查阅 Doc 得知需要设置为 CK_FRAMERATE_LIMITS (下简称 LIMITS)为 0x00000021 也就是 CK_BEHRATE_SYNC | CKFRAMERATE_FREE ,根据下面的解释,即为不锁帧。然后就...好了...确实也没想到会这么顺利()


      顺便又根据这里提到的这个枚举类型做了个自定义锁帧功能。自定义锁帧功能会将 LIMITS 设置为 0x00000041 即 CK_BEHRATE_SYNC | CK_FRAMERATE_LIMIT 。只有设置在这个模式下 CKTimeManager::SetFrameRateLimit() 的设定值才会生效。mod 的第二个选项就可以修改该项的值。


      IP属地:上海3楼2021-01-31 21:57
      回复
        3. Q&A
        为了回答以下的问题, 又写了个非常小的 mod:Statistica 。
        项目传送门:https://github.com/Swung0x48/Statistica
        同时也非常感谢变木和云居提供的支持!


        IP属地:上海4楼2021-01-31 21:58
        回复
          原来锁帧的原理究竟是什么呢?
          得到了窗口化高帧后,再回去倒推游戏内开/关垂直同步究竟做了什么,可以发现打开游戏内垂直同步设定的 LIMITS 是 0x0000011 (不会改动当前的 FrameRateLimit 设定 ), 关闭垂直同步时 LIMITS 设定值是 0x00000041 ,且会同时将 FrameRateLimit 的设定值设为 60。
          即开启原生垂直同步相当于 FramerateUnlocker 的模式 0, 关闭原生垂直同步相当于 FramerateUnlocker 的模式 2 同时设定 FramerateCap 的值为 30.



          因此这两个设置导致锁帧的原理不同。开启垂直同步时,根据文档原意,游戏的渲染会等待屏幕的 Vertical Blank Signal (垂直空白信号?下面详细说明)。而关闭垂直同步时,实则是将最高的帧率限制在 60fps。
          这个差别也许也可以解释为什么主显示器有较高刷新率时开启垂直同步会获得更高的帧率的原因。


          IP属地:上海6楼2021-01-31 22:03
          收起回复
            既然如此,那么为什么原来全屏不锁帧?
            简单回答:我不知道。
            但是我可以说一些可能会导致这个结果的因素。
            可以通过 Statistica 得知,全屏模式下的 LIMITS 和 FrameRateLimit 的设定值是一样的。
            Docs 提到了会等待 Vertical Blank Signal (垂直空白信号?我没有查到一个被比较普遍接受的中文翻译,以下简称 VBS)。简单来说,VBS 在 16-bit 主机和 CRT 显示器以及模拟信号盛行的时代被广泛使用,用来同步主机的和显示的画面。具体工作原理是,在上一帧最后一行扫描完成以后和下一帧的第一行开始扫描之前就向显示器输出这个信号,让显示器在此时不要显示任何信息。而如今 LCD 技术、数字信号的成熟(甚至如今绝大多数的新显卡(例如从 10 系开始的 n 卡)都已经完全取消了模拟信号输出,显卡包装内不附赠 DVI 转 VGA 转接器,且即使是 DVI 也都是 DVI-I (24+1,纯数字信号) 不是 DVI-D (24+5,模拟+数字) 或者 DVI-A(24+4,纯模拟信号),至于 HDMI 和 DP 更是只能传输数字信号了)因此 VBS 逐渐退出了历史舞台。
            那么也许是窗口化的时候是有模拟的 VBS 输入到游戏中,而全屏的时候则没有从主机的视频硬件之间获得 VBS / 获得的 VBS 有问题,因此出了一些 bug 导致了高帧率。
            至于游戏究竟用了什么逻辑来获知 VBS?或者也许根本不是 VBS 的锅?我不得而知。欢迎补充!


            IP属地:上海7楼2021-01-31 22:09
            回复
              插一楼
              Statistica 通过调用 virtools 提供的 profiling 功能实现的 stats 同样给出了很有意思的结果。在窗口化模式下,打开游戏内垂直同步的窗口化模式下,帧生成时间中 RenderTime 占了超过 16ms (60 fps 下的帧生成时间为 1/60s,即 16.67ms),而别的所有项目趋近于 0。这是因为等待 SYNC 的时间是算在 RenderTime 中的。


              而关闭游戏内垂直同步时,可以看到 EstimatedInterfaceTime 占了主力。


              而这些时间的介绍如下


              EstimatedInterfaceTime 的计算方式是 (总帧时间 - (游戏逻辑处理时间 + 渲染时间))。原意通过这个计算出的值来估计窗口和界面的开销。但实际上,因为锁(限制)了帧速率,相当于是 Render 结束之后在等待一个指定的时间。
              因此可以发现,通过这两个值可以清楚的了解到究竟是什么原因无法开启高帧率。


              IP属地:上海8楼2021-01-31 22:15
              回复
                为什么 Ballance 不会像别的基于 vt 的游戏那样加速?

                其实是会的...最典型的例子是分数球在高低帧率下行为不同。
                至于为什么计时是准的,猜测是因为 Ballance 是从 TimeManager 直接获得了时间。通过累加本帧到上一帧的时间可以得知经过的时间同时可以实时更新分数。(这也是 Segment 计时的方式)这也可以解释非常高的帧数下为什么计时不准:因为时间短到低于单精度浮点精度了...但经过测试,在相对比较低的帧数下的计时是准的。
                https://http://www.bilibili.com/video/BV1Uz4y1o7SY 这个视频中也证实了这一点。


                IP属地:上海10楼2021-01-31 22:18
                回复
                  最后贴一张描述 vt 引擎渲染过程的说明
                  希望对你理解上述内容可以有一些帮助


                  IP属地:上海11楼2021-01-31 22:19
                  回复