【Unity3d】【相机】透视相机UI转换(3DUI+保持屏幕比例)

0. 基础知识点

  1. 正交相机
    正交相机的的orthographicSize ,是 二分之一的屏幕高度,即 orthographicSize = H/2。

  2. 透视相机
    相机的aspect为相机的视口的宽高比: aspect = W/H
    即: W = H * aspect
    透视相机的屏幕高度H 随着相机的中心距离和fov变化。公式为:
    H = distance * tan(fov*0.5) * 2

  3. 相机视口尺寸和屏幕分辨率

  4. 相机的宽高比aspect 等于 屏幕的 宽高比

  5. 当视口尺寸高度为H时,屏幕的高度为ScreenH,则可获得比例 PixelsPerSize = ScreenH / H

  6. Unity3d中,Sprite 的设置选项 Pixels Per Unit = 100,表示sprite的一个单位代表100像素。

  7. 因此,当设置正交相机渲染Sprite,若SpriteSize = ScreenSize时,正好将屏幕盖上,则有:
    SpriteSize.H * PixelsPerUnit = ScreenSize.H = orthSize*2 * PixelsPerUnit

因此得到:orthSize = ScreenSize.H / PixelsPerUnit / 2
此时,Sprite scale = 1的时候,就与UGUI相机渲染的结果一致。

1. 整合转换:

当需要物体在正交相机中的大小与在透视相机中的大小相同时,以正交相机中的显示大小为基础(eg.UI相机中的显示)

扫描二维码关注公众号,回复: 17006159 查看本文章
  • 方法1.0:在透视相机中移动物体的位置,来保证同样的显示大小。 (近大远小的原理)
    原理: 保证透视相机中的尺寸与正交相机的尺寸相同:
    即: H(透视) = H (正交)
    则:H(正交) = H(透视) = distance * tan(fov * 0.5) * 2 ,
    得到,在透视相机中,此物体应该距离相机 distance = H(正交)/ (tan(fov * 0.5) * 2).
    其中H(正交)= orthSize*2。
  • 方法1.1:由方法1.0可以知道,H与距离和fov都有关系。因此也可以单独修改fov,或者**同时修改distance和fov,**以得到相同的结果:
    • tan(fov*0.5) = H/(distance * 2) = orthSize * 2 /(distance * 2) = orthSize / distance
    • fov = Atan(orthSize / distance) / 0.5 = Atan(orthSize / distance) *2。
  • 方法2:在透视相机中,进行缩放,以保证显示同样的大小。
    1. 首先,需要获取在透视相机中,与在UI相机中相同比例时,与透视相机的距离和透视相机的fov,作为标准:
      标准时: scale = 1 时,得到 distance(0) 和 fov(0)。
      • 若标准尺寸安装UGUI的尺寸来计算,根据 [0.3.相机视口尺寸和屏幕分辨率] 中原理可以得到:
        • 实际的正交相机 orthSize = Screen.H /100 *0.5
        • H(正交)= distance (tan(fov0.5)*2)= orthSize *2
        • 所以,得到 distance * tan(fov*0.5) = Screen.H /100
        • 若fov固定,则可以得到distance
        • 若distance固定,则可以得到fov
        • 也可以获取distance * tan(fov*0.5) 的值,作为后面的计算。
        • (令 DXF = distance * tan(fov0.5) )(DXF: Distance x tan(Fov0.5f)
          由相机视口尺寸 H = distance * tan(fov*0.5) * 2 得到,
          H(x) = distance(x) * tan(fov(x)*0.5) *2
          所以,当distance和fov变化后,变化的比例为:
          S(x) = H(x)/ H(0)
          = distance(x) * tan(fov(x)*0.5) *2 /(distance(0)*tan(fov(0)*0.5)*2)
          = distance(x)*tan(fov(x)*0.5) / ( distance(0) * tan(fov(0)*0.5) )
          = DXF(x) / DXF(0)
          所在x时候的Scale(x) = scale(0) * S(x) ,即为放大后的比例。
    • 当fov不变的时候,简化为:
      S(x) = distance(x) / distance(0)

2. 注意:物体与透视相机的距离

  1. 普通情况下,物体与透视相机的距离向量为 deltaVec = camTr.position - tr.postion
  2. 但是,在计算透视相机中物体的缩放时,应当使用到物体在透视平接头中的平面距离:
    1. projDistance =Abs( Vector3.Dot(deltaVec,camTr.forward) )

3. 其他: 透视相机中,物体永远朝向相机:

设置 tr.transform.forward = camTr.forward。

猜你喜欢

转载自blog.csdn.net/yanchezuo/article/details/129420904
今日推荐