【问题标题】:iOS SceneKit what is inversedTransform? (for dummies)iOS SceneKit 什么是 inversedTransform? (对于假人)
【发布时间】:2021-06-03 17:46:10
【问题描述】:

我是 MetalSceneKit 的 3D 渲染新手。我看到需要将特定的“逆”变换传递给渲染器/着色器。我打印了变换,看不到它们之间的关系。谷歌搜索结果是一堆相当高级的主题。

所以我问一个像我这样的傻瓜的问题:

着色器的“反向”视图变换是什么意思?

如果我不反转变换会发生什么?

// Apple code below (with original comment):
// Pass view-appropriate image transform to the shader modifier so
// that the mapped video lines up correctly with the background video.

let sceneView = renderer as? ARSCNView,
let frame = sceneView.session.currentFrame 

let affineTransform = frame.displayTransform(for: .portrait, viewportSize: self.view.bounds.size)
let transform = SCNMatrix4(affineTransform)
let inverse = SCNMatrix4Invert(transform) // pass to shader


transform: 
SCNMatrix4(
m11: 0.0, m12: 1.0, m13: 0.0, m14: 0.0,
 m21: -1.5227804, m22: 0.0, m23: 0.0, m24: 0.0,
 m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, 
m41: 1.2613902, m42: -0.0, m43: 0.0, m44: 1.0)
----
inversed:  
SCNMatrix4(
m11: 0.0, m12: -0.6566935, m13: 0.0, m14: 0.0, 
m21: 1.0, m22: 0.0, m23: 0.0, m24: 0.0,
 m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0, 
m41: 0.0, m42: 0.8283468, m43: 0.0, m44: 1.0)

这里有一些信息表明上述矩阵是平移、旋转和缩放的组合。虽然 CGAffine 变换将它们拆分为不同的元素,但在这里它们都被夹在一起:

https://www.javatpoint.com/computer-graphics-3d-inverse-transformations

【问题讨论】:

  • 我的数学演讲不太好,但基本上,变换是一个矩阵,可以让你从一个坐标系转到另一个坐标系。它通过改变一个向量来做到这一点,你正在从一组基向量转换为另一组基向量。而逆变换则相反。如果您有一个变换,可以让您从世界坐标系转到视图坐标系(以便在乘以任何世界向量后成为视图向量),则反向执行相反的操作:将视图向量返回到世界向量。矩阵和变换在 3D 中是相同的,因为所有线性变换都只能表示为矩阵。
  • 基本上,这归结为线性代数和仿射变换。有文章和书籍可以更好地解释它,尽管我没有具体的链接。

标签: shader scenekit metal ios14 cgaffinetransform


【解决方案1】:

我发现了对对象坐标在传递到渲染器之前所经过的步骤的出色描述:

  1. 在渲染相机图像时,逆变换使用相机内在函数将相机 X、Y + 可选深度转换为对象空间。相机内在函数将 3D 转换为 2D,因此逆变换从 2D 变为 3D

const auto localPoint = cameraIntrinsicsInversed * simd_float3(cameraPoint, 1) * depth;

  1. 对象(本地)空间到世界空间(苹果示例中的 localToWorld 矩阵)(3x3 矩阵)
  2. 世界空间到视图/眼睛/相机空间 viewMatrix(3x3 矩阵,Z 轴指向观察者/相机,Y 轴向上)
  3. 使用查看投影矩阵(4x4 矩阵,具有 W 分量)查看空间到剪辑空间。 大于 W 的 X、Y、Z 将被剪裁或剔除 - 不渲染。使用matrix_float4x4_perspective 函数创建

我们现在有一个矩阵序列,可以将我们从 对象空间到剪辑空间,这是 Metal 期望的空间 由我们的顶点着色器返回的顶点。乘以所有 这些矩阵一起产生一个模型视图投影(MVP)矩阵, 这就是我们将实际传递给顶点着色器的内容,以便每个 顶点可以在 GPU 上乘以它。

// pseudocode, missing some matrix padding for multiplication purposes:
modelViewProjection = vertXYZ * localToWorld * viewMatrix * projectionMatrix

渲染器执行进一步的转换:

  1. 剪辑空间到 NDC(标准化设备坐标)(半立方体 x,y -1 到 1,z 0 到 1)
  2. NDC 到窗口像素位置

【讨论】:

    【解决方案2】:

    当相机捕获 SCNScene 时,场景深度数据会丢失 - 这是因为 3D 对象被映射到 2D 图像平面上。但是,如果我们想要进行反向变换,那么它对于仅考虑 2D 图像来重建 3D 场景是行不通的。我们还需要深度。这就是inversedTransform 的用途。

    【讨论】:

      猜你喜欢
      • 2016-09-16
      • 1970-01-01
      • 2018-07-05
      • 1970-01-01
      • 2011-08-07
      • 2017-02-20
      • 1970-01-01
      • 2019-11-03
      相关资源
      最近更新 更多