计算帧和纵横比指南以匹配相机 [英] Calculating frame and aspect ratio guides to match cameras

查看:27
本文介绍了计算帧和纵横比指南以匹配相机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Three.js 中可视化胶片相机裁剪和纵横比.请耐心等待,这是一道数学题,我无法用更小的词来形容它...

I'm trying to visualize film camera crop and aspect ratio in Three.js. Please bear with me, it's a math problem, and I can't describe it in lesser words...

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

Instead of just using CameraHelper, I'm using three slightly modified CameraHelper objects for each camera. The helper lines can be seen when looking at a camera (cone), or when looking through a camera, the helper lines effectively create guide lines for the current camera.

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

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

Monitor helper (white). Our frame aspect ratio here is 1.5. For example, if we plan to do a 2.35 (cinemascope) aspect ratio film with a camera of aspect ratio 1.5, this shows the crop area of the frame. So it needs to exactly fit the frame, with extra space either up and down or at the sides, but not both. Calculated in getFOVMonitor.

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

Screen helper (purple). We want full thing visible in the browser, and if the browser window dimensions/aspect ratio is different, we adjust the actual rendered Three.js camera so that it fits into the browser window and dimensions. So this helper always has the aspect ratio of current browser window, and focal length so that it fits the frame and monitor helper. Calculated in getFOVScreen

因此,根据我们实际首选的相机(帧助手),我们需要计算监视器相机并调整它的 fov,使其完全适合内部帧相机.然后我们还需要计算屏幕相机并调整它的fov,使框架相机完全适合里面.

So based on our actual preferred camera (frame helper), we need to calculate the monitor camera and adjust it's fov that it exactly fits inside frame camera. Then we also need to calculate the screen camera and adjust it's fov that the frame camera exactly fits inside.

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

My current solution appears almost correct, but there is something wrong. With long lenses (small fov, big focal length) it seems correct:

  • 查看,看起来正确:
  • 当前相机和前面的相机看起来都正确:
  • 仔细看,看起来是正确的:

但是在广角镜头(大光圈,小焦距)下,解决方案开始失效,白色监视器助手周围有额外的空间,例如:

But at wide lenses (big fov, small focal length) the solution starts to break, there is extra space around the white monitor helper, for example:

  • 仔细看,白色框应该从侧面接触到蓝色框:
  • 当前的摄像头和前面的摄像头都看错了,白框应该碰到蓝框的两边(都有很广的镜头):
  • 透过(非常宽的镜头)看,看起来不对,白框应该接触蓝框,蓝框应该接触紫色框:

所以我认为我对各种相机的计算是错误的,尽管结果看起来几乎足够接近".

So I think I'm calculating the various cameras wrong, although the result seems almost "close enough".

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

Here's the code that returns the vertical FOV, horizontal HFOV and aspect ratio, which are then used to configure the cameras and helpers:

// 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 是嫌疑人.

Why does this produce incorrect results when using large FOV / wide lenses? getFOVScreen and especially getFOVMonitor are the suspects.

推荐答案

你的方程 var hfov = fov * getAspectScreen(); 不正确.

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

The relationship between the vertical FOV (vFOV) and the horizontal FOV (hFOV) are given by the following equations:

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

同样,

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

在这些等式中,vFOVhFOV 以弧度为单位;aspectRatio = 宽/高.

In these equations, vFOV and hFOV are in radians; aspectRatio = width / height.

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

In three.js, the PerspectiveCamera.fov is the vertical one, and is in degrees.

three.js r.59

three.js r.59

这篇关于计算帧和纵横比指南以匹配相机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆