【问题标题】:OpenGL - Trouble With Custom Perspective Matrix & ShaderOpenGL - 自定义透视矩阵和着色器的问题
【发布时间】:2013-12-05 18:34:00
【问题描述】:

这是我生成透视矩阵的代码:

public static Matrix4f orthographicMatrix(float left, float right, float bot, 
    float top, float far, float near) {
    // construct and return matrix
    Matrix4f mat = new Matrix4f();
    mat.m00 = 2 / (right - left);
    mat.m11 = 2 / (top - bot);
    mat.m22 = -2 / (far - near);
    mat.m30 = -((right + left) / (right - left));
    mat.m31 = -((top + bot) / (top - bot));
    mat.m32 = -((far + near) / (far - near));
    mat.m33 = 1;
    return mat;
}
public static Matrix4f projectionMatrix(float fovY, float aspect, 
    float near, float far) {
        // compute values
        float yScale = (float) ((float) 1 / Math.tan(Math.toRadians(fovY / 2)));
        float xScale = yScale / aspect;
        float zDistn = near - far;
        // construct and return matrix
        Matrix4f mat = new Matrix4f();
        mat.m00 = xScale;
        mat.m11 = yScale;
        mat.m22 = far / zDistn;
        mat.m23 = (near * far) / zDistn;
        mat.m32 = -1;
        mat.m33 = 0;
        return mat;
}

在我的程序中,首先以正交透视渲染一个正方形,然后以投影透视渲染一个正方形。

但这是我的问题 - 当我的着色器按此顺序执行乘法时:

gl_Position = mvp * vec4(vPos.xyz, 1); 

仅显示使用投影透视渲染的正方形。但是当按这个顺序进行乘法运算时:

gl_Position = vec4(vPos.xyz, 1) * mvp;

仅显示使用正交透视渲染的正方形!所以很明显我的问题是在给定乘法顺序的情况下一次只显示一个正方形。

【问题讨论】:

  • 乘法顺序问题表明您在矩阵中存储组件的顺序存在问题。 mat * vec 等效于 vec * transpose (mat),换句话说,如果您使用的是行优先矩阵(就 GL 而言实际上是 transpose (mat))而不是列优先矩阵,您需要反转矩阵的顺序乘法。这也适用于复合乘法,您必须反转整个乘法序列,这就是为什么 D3D 和 OpenGL 之间的缩放、旋转和平移顺序是向后的。
  • @AndonM.Coleman 解决了它 - 我在投影矩阵构造中交换了“xy”值并使用了gl_Position = vec4(vPos.xyz, 1) * mvp;。非常感谢 - 把它变成一个答案,我会接受!
  • @AndonM.Coleman 你提出 OpenGL 和 D3D 之间的差异可以解释为什么会发生这种情况 - 我从 D3D 教程中得到投影矩阵代码,从 OpenGL 中得到正交代码。
  • @AndonM.Coleman 哎呀,这是我将代码复制到问题中的错误。我确实在我的实际代码中将 m33 设置为 1。
  • @AndonM.Coleman 我还没有实现模型视图部分,所以我所做的就是将透视矩阵传递给 MVP。

标签: opengl matrix glsl lwjgl


【解决方案1】:

乘法顺序问题表明您在矩阵中存储组件的顺序存在问题。

    mat * vec 等同于 vec * transpose (mat)

换一种说法,如果您使用行优先矩阵(就 GL 而言实际上是 transpose (mat))而不是列优先矩阵,您需要颠倒矩阵乘法的顺序。这也适用于复合乘法,您必须反转整个乘法序列。这就是为什么 D3D(行优先)和 OpenGL(列优先)之间的缩放、旋转和平移顺序是向后的。

因此,当您构建 MVP 矩阵时,它应该如下所示:

    projection * view * model  (OpenGL)

    model * view * projection  (Direct3D)


OpenGL 使用的列主矩阵乘法应该从右到左读取。也就是说,您从一个对象空间位置(最右边)开始,然后转换到剪辑空间(最左边)。

换句话说,这是转换顶点的正确方法...

gl_Position =  ModelViewProjectionMatrix   * position;

~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~
 clip space    object space to clip space    obj space

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多