换算方法

这个工具只做一件事:让同一个鼠标动作,在不同游戏、不同倍镜下对应同一段鼠标移动距离。 下面把它拆成四步讲清楚,最后附上校准方法和常见问题。

一句话版本:先把灵敏度换算成「转一圈鼠标要走多少厘米」(360° 距离), 跨游戏/跨倍镜时保持这个距离不变,再按目标游戏的公式反推灵敏度。

1. 核心:360° 转身距离

每个 FPS 引擎都有一个 yaw 常量:鼠标每移动 1 个 DPI 计数,视角转过多少度。 于是「转满 360° 需要移动多少厘米」只取决于三个东西:

cm/360 = 360 × 2.54 ÷ (yaw × DPI × 灵敏度)

为什么要乘 2.54?因为 DPI 的单位是「每英寸」,360 ÷ (yaw × DPI × 灵敏度) 算出来是英寸,乘 2.54 才是厘米。

这就是不同游戏之间唯一可以照搬的量。只要两边的 360° 距离相等,你在两个游戏里的转身速度、 拉枪所需的鼠标行程就一致。反推回目标游戏的灵敏度:

灵敏度 = 360 × 2.54 ÷ (yaw × DPI × cm/360)

DPI 是硬件参数,两边共用同一只鼠标;换鼠标/换 DPI 时,工具会保持 360° 距离不变, 自动帮你算出新的灵敏度。

1.5 eDPI 是什么

eDPI = DPI × 灵敏度。它把「鼠标 DPI」和「游戏内灵敏度」合成一个数, 用来在同一款游戏里比较两个人的鼠标速度。

注意:eDPI 只是中间量,不同游戏的 eDPI 不能直接比较,因为每个游戏的 yaw 不一样。 真正代表实际转动角度的是:

度 / 英寸 = yaw × eDPI,度 / 厘米 = yaw × eDPI ÷ 2.54

eDPI 也不包含 FOV / 倍镜信息,所以它不能用来判断「开镜后手感是否一致」。

例子:CS2 800 DPI × 1.5 = 1200 eDPI;Valorant 800 DPI × 0.4714 ≈ 377 eDPI。 两个 eDPI 看起来差很多,但乘以各自的 yaw 后都是约 26.4 度/厘米,实际转身速度一样。

2. 跨游戏:只差一个 yaw

所有游戏都用同一个「360° 距离」之后,跨游戏换算就只剩 yaw 的比值了。 例如 CS2 的 yaw 是 0.022、Valorant 是 0.07,所以在同样 DPI、同样 360° 距离下, Valorant 的灵敏度约为 CS2 的 0.022 ÷ 0.07 ≈ 0.31 倍。

工具里的 yaw 数据见 游戏数据。如果某个游戏的 yaw 不准,换算出的 360° 距离就会整体偏移, 这种偏移会同时影响所有目标游戏,所以先用「360° 转身测量法」校准来源游戏是最值得的一步。

2.5 统一手感的四种方法(核心)

「统一手感」不是只有一种算法。常见的有四种:360D(角度一致)、 MDH 100%(屏幕距离一致)、MDH 0%(屏幕速度一致)、 ViewSpeed(折中,接近 MDH 75%)。本工具主要实现前三种。

MDH 的通用公式(t 是匹配点,0 = 屏幕中心,1 = 屏幕边缘):

s_B = s_A × (yaw_A ÷ yaw_B) × θ_B ÷ θ_A,其中 θ = atan( t × tan(FOV/2) )

  • MDH 100%(t=1,屏幕边缘):化简成 s_B = s_A × yaw比 × FOV比
  • MDH 0%(t→0,屏幕中心):化简成 s_B = s_A × yaw比 × tan(FOV/2)比,也就是 1/放大倍率
  • 360D(角度一致):s_B = s_A × yaw比,完全不看 FOV

所以跨游戏时 FOV 不同,三种方法会给出不同结果;360D 只统一角度,不统一屏幕上的距离感。 完整推导和例子见仓库里的 docs/SENSITIVITY-MODEL.md。

3. 跨倍镜:系数 k

开镜后视野(FOV)变小。按 MDH 100%(屏幕距离) 的近似,倍镜灵敏度按 FOV 比例缩放:

k = FOV_倍镜 ÷ FOV_裸,灵敏度_倍镜 = 灵敏度_裸 × k

等价写法是 360_倍镜 = 360_裸 ÷ k。这里的 FOV 一律用真实水平视角, 所以不同口径的 FOV 要先换算成真实水平值再相除(见下一节)。

注意:这只是 MDH 100%。按文章,CS/Valorant 的倍镜原生默认接近 MDH 100%, 而 Apex/R6 接近 MDH 0%(倍镜灵敏度 ≈ 裸镜 ÷ 放大倍率)。本工具目前统一用 MDH 100%, 以后会加「方法选择」来匹配各游戏原生行为。

「放大倍率」是另一个概念:放大倍率 = tan(FOV_裸/2) ÷ tan(FOV_倍镜/2)。 它用来判断两边的倍镜是不是同一档;如果两边倍镜倍率差太多,结果区会提示「不同级」。

4. FOV 的三种口径

不同游戏在设置里显示的 FOV 数值,含义并不一样。换算时先识别口径,再统一成真实水平 FOV:

  • h(16:9 真实水平):显示值就是 16:9 下的水平视角,例如 Valorant 锁死的 103°。
  • h4x3(4:3 基准):显示值以 4:3 屏幕为基准,16:9 下实际水平视角会更大。 CS2 的 90 在 16:9 下其实是 106.26°。
  • v(垂直 FOV):显示值是垂直视角,需要乘以屏幕宽高比换成水平。

统一成真实水平 FOV 的公式(ar 为显示器宽高比,16:9 即 1.7778):

  • h4x3 → 水平:2 × atan( tan(FOV/2) × ar ÷ (4/3) )
  • v → 水平:2 × atan( tan(FOV/2) × ar )
  • 水平 → 垂直:2 × atan( tan(FOV/2) ÷ ar )

所以换显示器比例(比如 16:9 → 21:9)时,水平 FOV 会变、倍镜系数也会跟着变; 工具里每一侧都有独立的「显示器宽高比」选项。

5. 校准:360° 转身测量法

  1. 进入游戏的训练场/安全区域,面对一个容易辨认的参照物。
  2. 把鼠标放在鼠标垫的一端,慢慢转身,直到视角正好转满 360° 回到原参照物。
  3. 量出鼠标在鼠标垫上走过的距离(厘米)。
  4. 把厘米数填进工具的「裸镜 360° 距离」,目标游戏的灵敏度会自动按这个实际手感重算。

如果测出来的 360° 距离和工具按 yaw 算出来的差很多,说明该游戏的 yaw 或你填的灵敏度需要复核; 也可以反过来用测量值校准 yaw:yaw = 360 × 2.54 ÷ (DPI × 灵敏度 × 实测 cm/360)。

开镜灵敏度同理:在游戏内测某个倍镜的 360° 距离,与裸镜对比,就能得到该倍镜的实际系数 k, 再和工具里的 FOV 比例对照,判断是数据问题还是游戏本身的缩放规则不同。

6. 这个工具的计算流程

  1. 来源侧:由裸灵敏度 / 360° 距离确定一个「手感真值」(360° 距离)。
  2. 算出来源侧裸镜与所选倍镜的真实水平 FOV,得到来源倍镜系数。
  3. 目标侧:裸镜 360° 距离与来源相同,按目标倍镜系数换算出目标倍镜的 360° 距离。
  4. 用目标游戏的 yaw 与 DPI 反推灵敏度,得到最终要填进游戏的值。

页面底部的「推导过程」会把每一步的数值展开,方便核对。

常见问题

为什么 CS2 的 FOV 90 在工具里显示 106.26°?

因为 CS 的 FOV 设置以 4:3 为基准。16:9 显示器更宽,同样的设置会露出更多水平视野: 2 × atan(tan(90/2) × (16/9) ÷ (4/3)) ≈ 106.26°。

为什么倍镜灵敏度要用 FOV 比例,而不是倍率?

「倍率」描述的是画面放大的视觉倍率(正切关系),而鼠标转动的角速度与 FOV 近似成线性关系。 本工具采用线性角速度假设:k = FOV_倍镜 / FOV_裸。 对绝大多数倍镜,两种算法差异不大;倍率特别高(如 12x)或 FOV 接近 180° 时误差会变大。

Apex 的 FOV 110 为什么不是标准的 124.59°?

Apex 的菜单 FOV 与标准 4:3 基准换算略有偏差:社区实测菜单 110 约为真实水平 123.27°, 而标准公式给 124.59°。工具里对 Apex 使用统一的缩放系数(fovScale ≈ 0.9864), 并且裸镜与倍镜使用同一套缩放,保证 1x 镜和裸镜一致。

换显示器比例(16:9 → 21:9)要改什么?

改两侧的「显示器宽高比」。游戏内 FOV 设置值不变时,水平 FOV 会变,倍镜系数随之变化; 垂直 FOV 保持不变。工具会按新的比例重新计算 H/V FOV 与倍镜系数。

为什么有些游戏只有一条灵敏度?

Valorant、CS2 这类游戏没有独立的 ADS 灵敏度滑条,开镜灵敏度由游戏按 FOV 自动缩放 (CS 由 zoom_sensitivity_ratio_mouse 控制)。工具仍然会算出每个倍镜「等效」的灵敏度, 方便你理解或用手柄/驱动软件做映射。

数据不准怎么办?

所有数据都在仓库的 src/data/games.ts 里,可以按你的实测值修改后重新构建。 改完建议跑一遍 npm test,并用 360° 转身测量法复核。

精度与限制

  • 线性角速度假设在 FOV 很大(接近 180°)或倍率极高时误差会变大。
  • 不同游戏的 ADS 缩放规则可能不是纯 FOV 比例,实际手感可能有细微差异。
  • 游戏版本更新可能改变 FOV 或灵敏度曲线,数据需要定期复核。
  • 本工具只做数值换算,不读取游戏文件、不上传任何数据。