python - Python 中的 OpenGL 透视矩阵

标签 python opengl matrix perspectivecamera

我正在尝试在 python 中构建透视变换矩阵以用于 pyOpenGL。我的 View 和模型转换工作正常,但是当我应用我的投影转换时,我得到一个空白屏幕(应该在从 (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 需要它的方式。我已尝试在不转置的情况下发送矩阵,并且它对输出没有(可见的)影响。

这是顶点着色器:

#version 330 core

layout(location = 0) in vec3 position;
uniform mat4 MVP;

void main()
{
    vec4 p = vec4(position, 1.0);
    gl_Position = MVP * p;
}

有人可以确定我的转型可能存在的问题吗?

编辑:我已经获取输出矩阵并手动完成计算。应用透视划分后,平截头体边缘上的所有点都出现在 NDC 框上,近点和远点的 z 分别转换为 -1、+1(由于舍入误差,精度较低)。对我来说,这表明我的数学是正确的,问题出在别处。这是输出矩阵:

[ 1.93137085  0.          0.          0.        ]
[ 0.          2.41421356  0.          0.        ]
[ 0.          0.         -1.002002   -1.        ]
[ 0.          0.          0.2002002   0.        ]

最佳答案

既然你说你是从 glm::perspective 工作的,那么让我们分析一下你的代码并与之进行比较。存在严重的不一致:

glm::透视

    assert(aspect != valType(0));
    assert(zFar != zNear);

#ifdef GLM_FORCE_RADIANS
    valType const rad = fovy;
#else
    valType const rad = glm::radians(fovy);
#endif

    valType tanHalfFovy = tan(rad / valType(2));
    detail::tmat4x4<valType> Result(valType(0));
    Result[0][0] = valType(1) / (aspect * tanHalfFovy);
    Result[1][1] = valType(1) / (tanHalfFovy);
    Result[2][2] = - (zFar + zNear) / (zFar - zNear);
    Result[2][3] = - valType(1);
    Result[3][2] = - (valType(2) * zFar * zNear) / (zFar - zNear);
    return Result;

注意下面一行:

Result[2][2] = - (zFar + zNear) / (zFar - zNear);

将其与您的等效项进行比较:

a_33 = (z_near + z_far)/(z_near - z_far)

请注意,整个语句前面有一个负号(-)。你的版本没有这个。

关于python - Python 中的 OpenGL 透视矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35369483/

相关文章:

matrix - Gnuplot:制作用矩阵生成的 map 的 gif?

matrix - 如何在 Eigen 中展开矩阵?

python - 两个 2d NumPy 数组中一行中所有元素之间的差异?

python - 使用 Python 和 Selenium 进行抓取 - 如果元素不存在,我应该如何返回 'null'

opengl - 在着色器中访问时,OpenGL如何决定使用MAG_FILTER和MIN_Filter?

带和不带照明的 OpenGL 顶点颜色

python - 如何从多个二维数组创建 numpy 矩阵/二维数组?

Python:确定实际当前模块(不是 __main__)

python - 如何使用 PIL 获得日本文本到图像的正确输出?

java - 如何绘制球体的中半部分(在代码中)