您当前的位置:首页> 行业动态 >正文
和FPS游戏有关的鼠标参数杂谈

2023-02-01 19:03:54     来源 : 哔哩哔哩

鉴于我看到的大部分关于鼠标参数的讨论都缺少一些对游戏机制的了解和定量的分析,我决定给大家分享一些我了解的,但不太能在讨论中看到的东西。

首先介绍一下我的背景。我是学计算机的,能看懂基本的代码,了解一些硬件的基本知识。我修过计算机图形学的课,写过光栅化渲染的代码,看过一些起源引擎的代码,也写过一些FPS的DEMO,所以知道游戏里是怎么显示画面,怎么转动视角,怎么判定命中的。但我不是专业做游戏或者硬件的,所以我了解的东西不一定准确,欢迎专业人士补充指正。


【资料图】

Hitscan武器的命中机制

为了理清瞄准与命中的关系,这里简要介绍一下hitscan型武器的命中机制。在游戏中,我们看到的画面是由一个虚拟的camera(通常位于角色头部)拍到的画面。准星通常在camera的中心,瞄准的方向通常用一个三维的向量(x, y, z)表示,我们通常只在意这个向量的方向,而不在意它的长度。游戏会在每一帧判断我们是否按下了开枪键,如果按下了,就会以camera为原点(极少数游戏会以枪口为原点)发出一条指向(x, y, z)的射线,与这条射线相交的第一个hitbox就是我们击中的目标,不考虑子弹的飞行时间,也就是所谓的即时命中。

有的游戏击中判定是在本地完成的,由本地客户端直接把是否击中目标告诉服务器。这样的一个优点是所见即所得,瞄准了一定能打中,但对延迟稍高的玩家不公平。

有的游戏则是把开枪那一帧的朝向(x, y, z)等数据告诉服务器,由服务器根据一套算法来补偿延迟,判断是否击中。这样更加公平,但瞄准了不一定能打中。

由于击中判定在哪里发生不是玩家能控制的,所以下面我们假设判定是在本地发生的,也就是只要在开枪的那帧里上述射线与目标hitbox相交就算击中。注意这里的射线与hitbox都只是游戏里虚拟的几何对象,判定的精度是由游戏中的浮点数精度决定的,几乎可以看成是绝对精确的,与显示在屏幕上的分辨率无关。这里的帧也是游戏中的逻辑帧,不一定对应显示器上的一帧。

实际中确实可能存在屏幕正中心(准星)看起来已经在目标hitbox边缘对应的像素上了,但仍然偏了少于一个像素对应的角度的情况。但鉴于一般目标的hitbox在屏幕上远不止一个像素,屏幕正中心正好在边缘那个像素上还没打中的概率非常低,我们可以认为对hitscan武器来说,只要开枪时屏幕正中心在hitbox上就能命中,相信大家也是这么练习的。

灵敏度与跳像素

虽然游戏中位置和角度的精度可以很高,但由于屏幕分辨率有限,我们肉眼能看到的精度是受限的。如果采用上面“屏幕正中心在目标上就能打中”的观点,我们只需要看起来能够“逐像素”地转动视角,操作的精度在视觉上就足够精细了。我相信这个标准对绝大部分人来说(包括最高水平的职业哥)都是足够的。下面的讨论都是基于这个观点展开的。

那怎样才能不跳像素呢?首先,我们需要知道鼠标给电脑的输入是离散的,鼠标向电脑报告的最小单位是一个“点”,一次不可能报告0.5个“点”。这个“点”就是所谓dots per inch(DPI)中的dot。注意这个“点”与游戏中的像素并没有直接的对应。在起源引擎中开启原始输入并关闭鼠标加速的情况下,鼠标每回报一个点视角会转(灵敏度*0.022)度(0.022是m_yaw值)。而在1080p屏幕106度水平fov(csgo中16:9的默认值)的情况下,屏幕中心的一个像素大概对应0.08度。为了能够“逐像素”地转动视角,我们希望鼠标报告一个点转动的角度要小于一个像素对应的角度。也就是说只要我们的游戏灵敏度低于(0.08/0.022约等于3.6)就不会跳像素,除非你的鼠标有问题,在极低速移动的时候还是每次至少报告2个以上的点。

我认识的绝大部分人只要用不低于800的dpi,在csgo中灵敏度都不会超过3.6,所以灵敏度通常不会导致跳像素。

对起源引擎中这段逻辑感兴趣的可以看 github.com/nillerusr/source-engine/blob/master/game/client/in_mouse.cpp 中的MouseMove函数。由于用鼠标控制视角转动的逻辑很简单,大部分游戏的实现都是类似的,所以只要开启原始输入并关闭鼠标加速,要求也是类似的(当然由于分辨率、fov和yaw不同,具体的游戏灵敏度要求会不同)。

标称回报率与实测回报率

一般回报率不超过1000hz的鼠标用的都是USB HID协议。在这个协议下,电脑每隔(1/回报率)秒会主动向鼠标查询移动了多少个点,称为轮询。既然是电脑规律地问鼠标,为什么我们用一些软件测出来的回报率会无法保持标称回报率呢?

一种情况是,鼠标在两次电脑询问的间隔中移动了不到一个点的距离,因此没有向电脑回报数据,测试软件中就没有记录到数据。假设我们使用的是1600dpi 1000hz回报率的鼠标,为了让鼠标每1ms至少报告一个点,我们需要保持鼠标的移动速度在(2.54/1600*1000=1.5875)(cm/s)以上。当我们在测试时,如果鼠标有较大的变向,通常总会有至少1ms以上的时间鼠标的速度达不到1.5875cm/s,因此测出来的回报率必然会低于1000hz。

当然还有另一种可能的情况,就是鼠标虽然在两次电脑的查询间移动了超过一个点的距离,但没有及时向电脑回报。这有可能是传感器给mcu(也就是鼠标上的处理器)的数据有延迟,也可能是mcu没有及时回报给电脑。根据我浅薄的嵌入式经验,以USB HID协议的传输量,在有线的情况下维持1000hz的回报频率对大部分mcu的性能来说都是绰绰有余的。也就是说如果鼠标在高速移动的情况下回报率有大的波动,更有可能是传感器或者无线传输出了问题,当然也可能纯粹是mcu的固件写搓了。

如果对鼠标和电脑间传了什么数据感兴趣,可以尝试用wireshark抓抓包,能抓到鼠标向电脑报告的移动和按键数据。我发现电脑和G304似乎会将查询缓存,鼠标可以在电脑的下一次询问之后再回报上一次询问的结果,而不丢失询问的历史,从而减少无线延迟对回报率的影响。

对于回报率超过1000hz的鼠标,似乎没有通用的通信协议,但我觉得用的应该也是电脑向鼠标轮询的模式,这样对电脑性能的影响更可控一些。

回报率与游戏中的性能

那么多少回报率够用呢?假设mcu和传感器能及时稳定地回报数据,采用上面“屏幕正中心在目标上就能打中”的观点,假设屏幕上至少有一帧时间(高刷显示器上不足10ms)准星在目标上,那只需要保证每一帧里至少有一次鼠标回报就行了(就算回报了两次也会被合成一次)。这大概需要鼠标的回报率至少高于显示器的刷新率。

当然,我们可以再严格一点。由于竞技游戏的帧数通常可以高于显示器的帧数,所以游戏引擎是可以允许出现瞄准的那一帧不在屏幕上显示的情况的。但就算这样,我们也只需要回报率高于游戏帧数就行了。不过这种准星在目标上不到10ms的瞄准往往会被认为是不稳定的神经枪,对按下鼠标左键的时机要求太高了,最好通过练习尽量避免这种情况出现。

实际情况中鼠标的性能会有波动,所以回报率最好能再高一点。我觉得只要回报率波动不大,能达到游戏帧数的两倍应该对绝大部分人来说都够用了(包括最高水平的职业哥)。 过高的回报率会影响游戏的帧数,反而可能减少我们能命中的总时间。

由于我的电脑很少能达到500以上的游戏帧率,我觉得1000hz回报率是一个可以接受的参数。

应该关心什么性能

就我个人的水平和手上的鼠标来说,我不太能感受到PMW3360以上传感器的性能差距,许多职业哥的鼠标也是停留在PMW3360,与之类似的hero甚至更差的PMW3310上。我感觉在PMW3360的基础上,鼠标的模具和重量对游戏手感的影响要显著得多。当然,由于我用的是自己设计的鼠标外壳,如果有性能更好,更省电,价格也合理的鼠标主板出现,我可能也会考虑换个主板玩玩。

假设有一个人对鼠标传感器和mcu的敏感度远高于我,那什么参数会显著地影响到他的游戏体验呢?我暂时能想到以下这几个:

首先是mcu和传输的稳定性。如果一个鼠标有1000hz的回报率,但由于mcu的固件写搓了,或者受到无线干扰,回报时间经常有10ms以上的波动,那确实可能会导致平滑移动鼠标时画面抖动,影响实际的游戏体验。不过我认为目前大厂基本都能做好这一点。我们可以通过保持鼠标高速移动时看回报点时间间隔的稳定性来判断这个参数的好坏。只要大厂的程序员水平正常,我相信鼠标低速移动时mcu和传输的稳定性是不会更差的,只不过可能无法从mousetester一类测试软件中看出来(因为鼠标移动不足1个点时不会回报)。

接着是传感器的长距离一致性,也就是鼠标每次移动相同的一大段距离时,传感器回报总点数的稳定性。传感器回报的点数与我们游戏中视角转动的角度直接相关,我们当然希望鼠标每次移动相同的距离,视角就能转动相同的角度。目前网上测试得更多的是鼠标实际dpi与标称dpi的偏差,这个我倒是觉得没那么重要。实际dpi与标称dpi的偏差可以通过灵敏度来补偿,假设鼠标的标称dpi是1000,但实际dpi是900,我们只需要把灵敏度除以0.9就能得到基本一样的手感。但如果一个鼠标移动1英寸时而回报900个点,时而回报1100个点,那就算实际dpi的期望值与标称的1000一样,也会极大地影响游戏体验。

然后是传感器的稳定性,也就是最近一些讨论中提到的PAW3370可能存在的问题。我们希望在匀速移动鼠标,鼠标回报率稳定时,每次鼠标回报的点数也是稳定的。由于传感器在侦测到移动后不一定会即时报告给mcu,有可能存在鼠标移动一大段距离回报的总点数稳定,但其中的每一次回报点数波动很大的情况。这种情况对甩枪的影响或许不大,但可能会在平滑移动鼠标时造成画面抖动。体现在测试结果上,就是匀速移动鼠标时鼠标向电脑报告的时间间隔稳定,但每次报告点数的波动很大。

最后是延迟。但根据网上的数据,鼠标延迟已经到10ms的量级了,和游戏的帧生成时间差不多,我觉得改进的空间可能不会很大,人能感知到的变化也有限,能达到目前大厂旗舰的水平就基本够用了。

结语

在了解了上面的这些知识,自己实际做了一些小测试后,我就很少纠结鼠标传感器了。

另外大家可以试试我写的小玩具 benkyoujouzu.github.io/fps-mouse-tester ,这个DEMO会在显示器的每一帧里在准星瞄准的位置留下一个记号,让大家对视角的转动速度有一个直观的感受。

标签: 的情况下 移动鼠标

X 关闭