简体   繁体   English

GLKit与金属透视矩阵的区别

[英]GLKit vs. Metal perspective matrix difference

I'm reading a Metal tutorial on raywenderlich.com, where it introduces a pure Swift float4x4 helper class . 我正在阅读raywenderlich.com上的Metal 教程 ,在那里它介绍了一个纯粹的Swift float4x4 助手类 99% it's just wrapper around GLKit functions, except one function which really puzzles me: 99%它只是包装GLKit函数,除了一个真正困扰我的函数:

  static func makePerspectiveViewAngle(_ fovyRadians: Float, aspectRatio: Float, nearZ: Float, farZ: Float) -> float4x4 {
    var q = unsafeBitCast(GLKMatrix4MakePerspective(fovyRadians, aspectRatio, nearZ, farZ), to: float4x4.self)
    let zs = farZ / (nearZ - farZ)
    q[2][2] = zs
    q[3][2] = zs * nearZ
    return q
  }

Why does it need to change q[2][2] and q[3][2] . 为什么需要改变q[2][2]q[3][2] Is this some incompatibility between Metal's and GLKit's coordinate system? 这是Metal和GLKit坐标系之间的一些不兼容吗?

Is this a particular choice this tutorial made? 这是本教程的特别选择吗? If not, are there any other incompatibilities between GLKit and Metal mathematics? 如果没有,GLKit和Metal数学之间是否还有其他不兼容性?


Update : I found a nice illustration about Metal's clip space coordinate system from the WWDC 2016 Session: Adopting Metal I. 更新 :我在WWDC 2016年会议上发现了一个很好的关于Metal的剪辑空间坐标系的插图:采用金属I.

裁剪空间

Quoting from this forum question 引用此论坛问题

OpenGL uses different clip-space coordinates than Metal (in GL, z goes from -1 to 1, while in Metal z goes from 0 to 1), so using GLKMatrix4MakePerspective doesn't give you a matrix that properly transforms from eye space to clip space. OpenGL使用与Metal不同的剪辑空间坐标(在GL中,z从-1变为1,而在Metal z中从0变为1),因此使用GLKMatrix4MakePerspective不会为您提供从眼睛空间到剪辑正确转换的矩阵空间。 Instead, it transforms half of the viewing volume behind the eye, causing sometimes-subtle clipping and culling issues. 相反,它会改变眼睛后面一半的观察体积,导致有时微妙的剪裁和剔除问题。 You can fix up the matrix you get back from GLK by setting the matrix elements that are relevant to depth by adding the following code to makePerspectiveViewAngle: 您可以通过将以下代码添加到makePerspectiveViewAngle来设置与深度相关的矩阵元素来修复从GLK返回的矩阵:

let zs = farZ / (nearZ - farZ) 让zs = farZ /(nearZ - farZ)

q[2][2] = zs q [2] [2] = zs

q[3][2] = zs * nearZ q [3] [2] = zs * nearZ

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 PWA 与 Safari 网站有什么区别? - What's the difference of a PWA vs. Safari website? [String]与[(String)]之间有什么区别? - What's the difference between [String] vs. [(String)]? 第一人称相机的金属视图和投影矩阵 - View and Projection Matrix in Metal for a First Person Camera 在 AnyCancellable 上调用.cancel() 与制作 AnyCancellable 之间有区别吗? = SwiftUI 中的零? - Is there a difference between calling .cancel() on an AnyCancellable vs. making an AnyCancellable? = nil in SwiftUI? “应用程序目标”与“框架目标”中的 Xcode Swift 导入代码——有什么区别? - Xcode Swift Import Code Within "an App Target" vs. "a Framework Target" -- What is difference? 从coreData与Array.sort检索时,使用sortDescriptor之间在性能上有区别吗? - Is there performance difference between using sortDescriptors when retrieving from coreData vs. Array.sort? 重载方法,其中只有差异是可选的与非可选的类型 - overloading methods where only difference is optional vs. non-optional type String(contentsOf: URL).data(using: .utf8) 与 Data(contentsOf: URL) 的区别 - Difference of String(contentsOf: URL).data(using: .utf8) vs. Data(contentsOf: URL) 准备与选择 - .prepare vs. .select API与框架 - APIs vs. Frameworks
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM