OpenGL - 自定义透视矩阵的问题&着色器

时间:2013-12-05 18:34:01

标签: opengl matrix glsl lwjgl

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

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;

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

1 个答案:

答案 0 :(得分:2)

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

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