有没有办法移动 Scene Kit 相机的主点?

Posted

技术标签:

【中文标题】有没有办法移动 Scene Kit 相机的主点?【英文标题】:Is there a way to shift the principal point of a Scene Kit camera? 【发布时间】:2021-09-16 10:07:23 【问题描述】:

我想在 MacOS 上的 Scene Kit 中模拟移轴/透视控制镜头的移动。

假设用户将相机面向地面的一栋高层建筑,我希望能够移动“镜头”以使投影失真发生变化(参见例如Wikipedia)。

Apple 为 SCNCamera 提供了许多基于物理的参数(传感器高度、光圈叶片数),但我看不出有什么明显的。在Unity中似乎存在。

至关重要的是,我想移动镜头,使物体相对于相机保持在相同的位置。显然我可以移动相机来获得效果,但是对象需要在视口中保持居中(而且我也看不到修改视口的方法)。我尝试过直接修改 .projectionTransform 矩阵,但不成功。

谢谢!

【问题讨论】:

【参考方案1】:

SCNCamera 上没有开箱即用的 API。正如您所猜测的,必须创建一个自定义投影矩阵并将其设置为 projectionTransform 属性。

【讨论】:

想了很多。你有没有机会修改投影矩阵来达到这个效果?我自己尝试过数学运算,但到目前为止只设法获得了偏斜效应。【参考方案2】:

我终于对投影矩阵进行了正确的调整 - 遵循数学非常令人困惑,因为它是一个 4x4 矩阵,而不是您用于普通相机投影矩阵的 3x4 或 4x3,这也使得它尤其是搞不清它是期望行向量还是列向量。

无论如何,y 轴的正确元素是.m32

let camera = SCNNode()
camera.camera = SCNCamera()

let yShift: CGFloat = 1.0

camera.camera!.projectionTransform.m32 = yShift

大概.m31 会在 x 轴上移动,但我不得不承认我还没有测试过。

当我再想一想时,我也意识到我实际上想要的效果也包括移动相机。调整.m32 模拟移动传感器,这似乎会相对于相机移动被摄体,就好像你有一个广角镜头并且你正在移动作物一样。为了使主体在画面中居中,您还需要移动相机的位置。

在this blog post 尤其是this code 的帮助下,我也实现了这个:

let distance: CGFloat = 1.0 // calculate distance from subject here
let fovRadians = camera.camera!.fieldOfView * CGFloat.pi / 180.0
let yAdjust = tan(fovRadians / 2) * distance * yShift
camera.position = camera.position - camera.worldUp * yAdjust

(任何感兴趣的读者都可以从上面的源代码中计算出 x 轴偏移)

【讨论】:

以上是关于有没有办法移动 Scene Kit 相机的主点?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Scene Kit 或 ARkit 中的 Camera 渲染的视图中调暗灯光?

Unity 模仿scene视图相机视角移动

Unity 模仿scene视图相机视角移动

Scene Kit 的枢轴矩阵的语义是啥?

Swift Sprite Kit 相机运动

在OpenGL中平移和移动相机的正确方法?