我正在尝试在 Three.js 中可视化胶片相机裁剪和纵横比。请耐心等待,这是一道数学问题,我无法用更简短的语言来描述它......
我不只是使用 CameraHelper,而是为每个相机使用三个稍微修改过的 CameraHelper 对象。当查看相机(锥体)时,或者通过相机查看时,可以看到辅助线,辅助线有效地为当前相机创建引导线。
框架助手(带有渲染侧面的蓝色)。考虑到焦距和传感器或胶片尺寸,这是经过配置的并且应该是实际相机所看到的。计算在getFOVFrame.
监控助手(白色)。我们这里的帧长宽比是 1.5。例如,如果我们计划使用长宽比为 1.5 的相机拍摄长宽比为 2.35(电影院)的影片,则这将显示帧的裁剪区域。因此,它需要完全适合框架,上下或两侧都有额外的空间,但不能两者兼而有之。计算在getFOVMonitor.
屏幕助手(紫色)。我们希望在浏览器中看到完整的东西,如果浏览器窗口尺寸/长宽比不同,我们会调整实际渲染的 Three.js 相机,使其适合浏览器窗口和尺寸。因此,这个助手始终具有当前浏览器窗口的宽高比和焦距,以便它适合框架和监视器助手。计算于getFOVScreen
因此,根据我们实际首选的相机(帧助手),我们需要计算监控相机并调整它的视场,使其完全适合帧相机内。然后我们还需要计算屏幕相机并调整它的视场,使帧相机完全适合内部。
我当前的解决方案看起来几乎是正确的,但有一些问题。对于长镜头(小视场,大焦距),这似乎是正确的:


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



所以我认为我对各种相机的计算是错误的,尽管结果看起来几乎“足够接近”。
下面的代码返回垂直 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;
}
Run Code Online (Sandbox Code Playgroud)
为什么在使用大视场/宽镜头时会产生不正确的结果?getFOVScreen尤其getFOVMonitor是嫌疑人。
你的等式var hfov = fov * getAspectScreen();不正确。
vFOV垂直FOV ( ) 和水平FOV ( )之间的关系hFOV由以下等式给出:
hFOV = 2 * Math.atan( Math.tan( vFOV / 2 ) * aspectRatio );
Run Code Online (Sandbox Code Playgroud)
同样,
vFOV = 2 * Math.atan( Math.tan( hFOV / 2 ) / aspectRatio );
Run Code Online (Sandbox Code Playgroud)
在这些方程中,vFOV和 的hFOV单位是弧度;aspectRatio = width / height。
在 Three.js 中,PerspectiveCamera.fov是垂直的,单位是度。
三.js r.59
| 归档时间: |
|
| 查看次数: |
2319 次 |
| 最近记录: |