我正在raywenderlich.com上阅读Metal tutorial,在那里它引入了一个纯粹的Swift float4x4 helper class。 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
}
为什么需要更改q[2][2]
和q[3][2]
。这是Metal和GLKit坐标系之间的一些不兼容吗?
这是本教程的特别选择吗?如果没有,GLKit和Metal数学之间是否存在其他不兼容性?
更新:我在WWDC 2016年会议上发现了关于Metal的剪辑空间坐标系的一个很好的例子:采用Metal I。
答案 0 :(得分:4)
OpenGL使用与Metal不同的剪辑空间坐标(在GL中,z表示 从-1到1,而在Metal z从0到1),所以使用 GLKMatrix4MakePerspective并没有给你一个正确的矩阵 从眼睛空间转换到剪辑空间。相反,它改变了一半 眼睛后面的观察体积,有时会引起微妙的变化 剪切和剔除问题。你可以修复你得到的矩阵 通过设置与深度相关的矩阵元素,从GLK 将以下代码添加到makePerspectiveViewAngle:
让zs = farZ /(nearZ - farZ)
q [2] [2] = zs
q [3] [2] = zs * nearZ