我正在尝试在Three.js中可视化胶片相机裁剪和宽高比。请耐心等待,这是一个数学问题,我无法用较少的词语来描述......
我不是只使用CameraHelper,而是为每个摄像头使用三个稍微修改过的CameraHelper对象。在观察相机(锥形)时可以看到辅助线,或者当通过相机观察时,辅助线有效地为当前相机创建引导线。
框架助手(带有侧边渲染的蓝色)。考虑到它的焦距和传感器或胶片尺寸,这被配置并且应该是实际相机所看到的。以getFOVFrame
。
监控助手(白色)。我们的帧长宽比为1.5。例如,如果我们计划使用宽高比为1.5的相机拍摄2.35(电影放映机)宽高比胶片,则会显示画面的裁剪区域。所以它需要精确地适合框架,在上下两侧或两侧都有额外的空间,但不是两者都有。以getFOVMonitor
。
屏幕助手(紫色)。我们希望浏览器中显示完整的内容,如果浏览器窗口的尺寸/宽高比不同,我们会调整实际渲染的Three.js相机,使其适合浏览器窗口和尺寸。所以这个帮助器总是具有当前浏览器窗口的长宽比和焦距,以便它适合框架和监视器帮助器。以getFOVScreen
因此,基于我们实际首选的相机(帧辅助器),我们需要计算监视器摄像头并调整它的fov,使其完全适合帧内摄像机。然后我们还需要计算屏幕摄像头并调整帧摄像头完全适合内部的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
是嫌疑人。
答案 0 :(得分:2)
您的等式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 );
在这些等式中,vFOV
和hFOV
以弧度为单位; aspectRatio = width / height
。
在three.js中,PerspectiveCamera.fov
是垂直的,并且是度数。
three.js r.59