有没有办法移动 Scene Kit 相机的主要点?
Is there a way to shift the principal point of a Scene Kit camera?
我想在 MacOS 上的 Scene Kit 中模拟 tilt-shift/perspective-control 镜头的移动。
假设用户的相机面向地面的高楼,我希望能够移动 'lens' 以便投影失真移动(参见 Wikipedia)。
Apple 为 SCNCamera 提供了许多基于物理的参数(传感器高度、光圈叶片数),但我看不到任何明显的参数。它似乎存在于 Unity.
最重要的是,我想移动镜头,使物体相对于相机保持在相同的位置。显然我可以移动相机来获得效果,但对象需要在视口中居中(而且我也看不到修改视口的方法)。我试过直接修改.projectionTransform矩阵,但是没有成功。
谢谢!
SCNCamera
上没有 API 开箱即用。正如您所猜测的那样,必须创建一个自定义投影矩阵并将其设置为 projectionTransform
属性.
我终于算出了对投影矩阵的正确调整 - 按照数学计算很混乱,因为它是一个 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 and in particular 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 轴偏移)
我想在 MacOS 上的 Scene Kit 中模拟 tilt-shift/perspective-control 镜头的移动。
假设用户的相机面向地面的高楼,我希望能够移动 'lens' 以便投影失真移动(参见 Wikipedia)。
Apple 为 SCNCamera 提供了许多基于物理的参数(传感器高度、光圈叶片数),但我看不到任何明显的参数。它似乎存在于 Unity.
最重要的是,我想移动镜头,使物体相对于相机保持在相同的位置。显然我可以移动相机来获得效果,但对象需要在视口中居中(而且我也看不到修改视口的方法)。我试过直接修改.projectionTransform矩阵,但是没有成功。
谢谢!
SCNCamera
上没有 API 开箱即用。正如您所猜测的那样,必须创建一个自定义投影矩阵并将其设置为 projectionTransform
属性.
我终于算出了对投影矩阵的正确调整 - 按照数学计算很混乱,因为它是一个 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 and in particular 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 轴偏移)