代码之家  ›  专栏  ›  技术社区  ›  Alex Stone

iOS SceneKit什么是逆变转换?(适用于假人)

  •  0
  • Alex Stone  · 技术社区  · 4 年前

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

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

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

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

    // 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

    0 回复  |  直到 4 年前
        1
  •  0
  •   Alex Stone    4 年前

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

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

    const auto-localPoint=相机固有转换*simd_float3(相机点,1)*深度;

    1. 对象(局部)空间到世界空间(苹果示例中的localToWorld矩阵)(3x3矩阵)
    2. 世界空间视图/眼睛/相机空间视图矩阵(3x3矩阵,Z轴指向观察者/相机,Y轴指向上)
    3. 使用视图投影矩阵(4x4矩阵,具有W分量)将视图空间转换为剪辑空间。 X、 大于W的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
  •  0
  •   Andy Jazz    3 年前

    当相机捕获SCNScene时,场景深度数据会丢失,这是因为3D对象被映射到2D图像平面上。然而,如果我们想进行逆变换,那么仅考虑2D图像重建3D场景是行不通的。我们也需要深度。就是这样 inversedTransform 是为了。