【问题标题】:Calculating frame and aspect ratio guides to match cameras计算帧和纵横比指南以匹配相机
【发布时间】:2023-03-08 09:51:01
【问题描述】:

我正在尝试在 Three.js 中可视化胶片相机裁剪和纵横比。请多多包涵,这是一道数学题,我无法用简单的语言来描述它......

我不只是使用 CameraHelper,而是为每个相机使用了三个稍微修改过的 CameraHelper 对象。在查看相机(圆锥)时可以看到辅助线,或者在通过相机查看时,辅助线有效地为当前相机创建引导线。

  • 框架助手(带有渲染侧面的蓝色)。考虑到它的焦距和传感器或胶片尺寸,这是配置并应该是实际相机所看到的。计算在getFOVFrame

  • 监视器助手(白色)。我们这里的帧长宽比是 1.5。例如,如果我们计划使用纵横比为 1.5 的相机制作纵横比为 2.35(电影放映机)的胶片,这将显示帧的裁剪区域。所以它需要完全适合框架,上下或侧面都有额外的空间,但不是两者兼而有之。计算在getFOVMonitor

  • 屏幕助手(紫色)。我们希望完整的东西在浏览器中可见,如果浏览器窗口尺寸/纵横比不同,我们调整实际渲染的 Three.js 相机,使其适合浏览器窗口和尺寸。所以这个助手总是有当前浏览器窗口的纵横比和焦距,以便它适合框架和监视器助手。计算在getFOVScreen

因此,根据我们实际首选的相机(框架助手),我们需要计算监控相机并调整它的 fov 以使其完全适合框架相机。然后我们还需要计算屏幕相机并调整它的fov,使框架相机正好适合里面。

我当前的解决方案看起来几乎是正确的,但是有一些问题。使用长镜头(小视野,大焦距)似乎是正确的:

  • 查看,看起来正确:
  • 当前摄像头和前面的摄像头看起来都正确:
  • 仔细查看,看起来是正确的:

但在广角镜头(大视野、小焦距)下,解决方案开始出现问题,白色监视器助手周围有额外的空间,例如:

  • 看过去,白色的盒子应该从侧面碰到蓝色的盒子:
  • 当前摄像头和前面的摄像头都看错了,白框应该碰到蓝框的两侧(都有很宽的镜头):
  • 通过(非常宽的镜头)看,看起来不对,白框应该碰到蓝框,蓝框应该碰到紫框:

所以我认为我计算的各种相机是错误的,尽管结果似乎几乎“足够接近”。

这是返回垂直 FOV、水平 HFOV 和纵横比的代码,然后用于配置相机和助手:

// BLUE camera fov, based on physical camera settings (sensor dimensions and focal length)
var getFOVFrame = function() {
  var fov = 2 * Math.atan( sensor_height / ( focal_length * 2 ) ) * ( 180 / Math.PI );
  return fov;
}
var getHFOVFrame = function() {
  return getFOVFrame() * getAspectFrame();
}

// PURPLE screen fov, should be able to contain the frame
var getFOVScreen = function() {
  var fov = getFOVFrame();
  var hfov = fov * getAspectScreen();
  if (hfov < getHFOVFrame()) {
    hfov = getHFOVFrame();
    fov = hfov / getAspectScreen();
  }  
  return fov;
}
var getHFOVScreen = function() {
  return getFOVScreen() * getAspectScreen();
}

// WHITE crop area fov, should fit inside blue frame camera
var getFOVMonitor = function() {
  var fov = getFOVFrame();      
  var hfov = fov * getAspectMonitor();
  if (hfov > getHFOVFrame())   {
    hfov = getHFOVFrame();
    fov = hfov / getAspectMonitor();
  }
  return fov;
}
var getHFOVMonitor = function() {
  return getFOVMonitor() * getAspectMonitor();
}

var getAspectScreen = function() {
  return  screen_width / screen_height;
}

var getAspectFrame = function() {
  return  sensor_width / sensor_height;
}

var getAspectMonitor = function() {
  return monitor_aspect;
}

为什么在使用大 FOV/广角镜头时会产生不正确的结果? getFOVScreen 尤其是getFOVMonitor 是嫌疑人。

【问题讨论】:

    标签: three.js


    【解决方案1】:

    您的方程式var hfov = fov * getAspectScreen(); 不正确。

    垂直 FOV (vFOV) 和水平 FOV (hFOV) 之间的关系由以下等式给出:

    hFOV = 2 * Math.atan( Math.tan( vFOV / 2 ) * aspectRatio );
    

    同样,

    vFOV = 2 * Math.atan( Math.tan( hFOV / 2 ) / aspectRatio );
    

    在这些等式中,vFOVhFOV 的单位是弧度; aspectRatio = width / height.

    在three.js中,PerspectiveCamera.fov是垂直的,以度为单位。

    three.js r.59

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 2014-08-01
      • 2023-03-08
      • 1970-01-01
      • 2011-03-31
      相关资源
      最近更新 更多