Unity3D中摄像机的FOV和Camera.ScreenToWorldPoint方法的关系
请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com
在Unity3D编程中经常会碰到以下的问题:
比如一开始的FOV为60度,后来设置为22度,可以通过怎样的公式,使得使用22度FOV对应生成的3D位置点,通过这个公式,可以转换到其位置点和使用60度生成的一样呢
当从一个FOV为60度的视角切换到22度的视角时,使用Camera.ScreenToWorldPoint函数生成的3D位置点会发生变化,因为FOV直接影响视锥体的宽度和高度。要解决这个问题,需要通过调整视锥体的缩放因子,来抵消FOV变化带来的位置偏移。
问题分析 当FOV变化时,屏幕坐标对应的世界坐标会随之缩放。假设有一个屏幕坐标screenPos,在FOV为60度时通过Camera.ScreenToWorldPoint生成一个3D位置点P60。当FOV变为22度时,假设生成的3D位置点为P22。我们需要找到一个转换公式,使得P22转换回P60。
FOV与世界坐标的关系 视锥体的高度(在深度为z处)与FOV通过以下公式相关:
$$ Heightz=2×z×tan(FOV2)\text{Height}_z = 2 \times z \times \tan\left(\frac{FOV}{2}\right)Heightz=2×z×tan(2FOV) $$
其中:
Height_z :在深度为z处的视锥体高度。 FOV:垂直视野角度。 z:深度(从摄像机到目标点的距离)。 视锥体的宽度和高度成比例地变化,具体公式为:
$$ Widthz=Heightz×Aspect Ratio\text{Width}_z = \text{Height}_z \times \text{Aspect Ratio}Widthz=Heightz×Aspect Ratio $$
对于两个不同的FOV(如60度和22度),可以计算出它们对应的视锥体高度比值。为了让FOV为22度时生成的世界坐标与FOV为60度时生成的一致,需要应用这个比值进行缩放。
缩放因子的推导 在FOV为60度时的视锥体高度:
$$ \mathrm{Heigth}_{60}=2\times \mathrm{z}\times \tan \left( \frac{60^o}{2} \right) $$
在FOV为22度时的视锥体高度:
$$ \mathrm{Heigth}_{22}=2\times \mathrm{z}\times \tan \left( \frac{22^o}{2} \right) $$
缩放因子: 需要将FOV为22度时的世界坐标缩放到FOV为60度的视锥体高度,因此缩放因子是这两个视锥体高度的比值:
$$ ScaleFactor=\frac{Height_{60}}{Height_{22}}=\frac{\tan \left( 30^{o} \right)}{\tan \left( 11^{o} \right)} $$
可以计算出这个缩放因子:
$$ \mathrm{ScaleFactor}=\frac{0.5774}{0.1944}\approx 2.97 $$
公式应用 在FOV为22度时生成的3D世界坐标P22可以通过如下公式转换为FOV为60度时的3D世界坐标P60: