我正在尝试用python构建一个透视转换矩阵,以便与pyOpenGL一起使用。我的视图和模型转换正在工作,但是当我应用投影变换时,我得到一个空白屏幕(应该是从(0,0,+1)看到原点处的一个三角形)。在
我已经看了一遍数学,据我所知,这个变换应该行得通,所以我需要另一双眼睛来帮助找到问题。在
def perspective(field_of_view_y, aspect, z_near, z_far):
fov_radians = math.radians(field_of_view_y)
f = math.tan(fov_radians/2)
a_11 = 1/(f*aspect)
a_22 = 1/f
a_33 = (z_near + z_far)/(z_near - z_far)
a_34 = -2*z_near*z_far/(z_near - z_far)
# a_33 = -(z_far + z_near)/(z_far - z_near)
# a_34 = 2*z_far*z_near/(z_far - z_near)
perspective_matrix = numpy.matrix([
[a_11, 0, 0, 0],
[0, a_22, 0, 0],
[0, 0, a_33, a_34],
[0, 0, -1, 0]
]).T
return perspective_matrix
projection_matrix = perspective(45, 600/480, 0.1, 100)
mvp_matrix = projection_matrix * view_matrix * model_matrix
我转置了矩阵,因为我很确定numpy存储的矩阵转置到OpenGL需要它的地方。我试着在不换位的情况下发送矩阵,它对输出没有(可见的)影响。在
这里是顶点着色器:
^{pr2}$有人能确定我的转变可能存在哪些问题吗?在
编辑:我已经得到了输出矩阵,并手工完成了计算。应用透视分割后,截锥边缘上的所有点都将沿着NDC框显示,近点和远点的z分别被转换为-1、+1(由于舍入误差,精度为+/-minor)。对我来说,这说明我的数学是对的,问题在别处。这是输出矩阵:
[ 1.93137085 0. 0. 0. ]
[ 0. 2.41421356 0. 0. ]
[ 0. 0. -1.002002 -1. ]
[ 0. 0. 0.2002002 0. ]
我已经解决了问题,发布信息以防将来有人遇到类似的问题。在
在构建模型、视图和投影矩阵时,我引入了行主矩阵和列主矩阵的混合。引入这些是因为numpy和OpenGL需要不同格式的矩阵。当单独操作这些矩阵是有效的,因为它们可以很容易地用numpy进行转置以产生正确的结果。在
合并婚姻时出现了问题。结果是这些转换以一种不一致和毫无意义的顺序进行,所有的点都被从屏幕上划掉了。这就隐藏了透视矩阵中的错误和复杂的调试。在
解决方案是确保所有矩阵在它们存储数据的方式上是一致的(要么全部是行主矩阵,要么是列主矩阵),并且在发送到OpenGL之前进行一次转换。在
既然您说您是从glm::perspective开始工作的,那么让我们分析一下您的代码与它进行比较。有一个严重的不一致:
glm::perspective
请注意以下行:
^{pr2}$将其与您的等效项进行比较:
注意,在整个语句前面有一个负号(
-
)。你的版本没有这个。在相关问题 更多 >
编程相关推荐