OpenGL ES 2.0:矩阵乘法问题

时间:2011-07-11 17:29:52

标签: iphone matrix opengl-es-2.0

我正在尝试使用OpenGL ES 2.0绘制四边形。 我的顶点着色器看起来像这样:

uniform mat4 mvp;
attribute vec4 position;
attribute vec4 color;
varying vec4 colorVarying;

void main()
{
    gl_Position = mvp * position;
    colorVarying = color;
}

如果我使用这些顶点:

-1.0f, -1.0f, 0.f, 1.f,
 1.0f, -1.0f, 0.f, 1.f,
-1.0f,  1.0f, 0.f, 1.f,
 1.0f,  1.0f, 0.f, 1.f

和这个矩阵(按列主顺序,以及所有后面的矩阵):

0.5,0,0,0,
0,  1,0,0,
0,  0,1,0,
0.5,0,0,1

四边形覆盖了视口的右半部分。实际上,如果我将这两个矩阵相乘,我得到顶点

0,    -1,     0,     1,
1,    -1,     0,     1,
0,     1,     0,     1,
1 ,    1,     0,     1,

如果我使用那些顶点和单位矩阵,我会得到相同的结果。因此似乎正确地完成了乘法。

现在,如果我乘以这些顶点(A):

-100.0f, -100.0f, 301.0f, 1.0f,
 100.0f, -100.0f, 301.0f, 1.0f,
-100.0f,  100.0f, 301.0f, 1.0f,
 100.0f,  100.0f, 301.0f, 1.0f,

通过这个矩阵(M):

0.4170         0         0         0
     0    0.5560         0         0
     0         0   -1.2220   -1.0000
     0         0  444.4440         0

我得到这些顶点(B):

 0.2075,    0.2766,   -0.9892,    1.0000
-0.2075,    0.2766,   -0.9892,    1.0000,
 0.2075,   -0.2766,   -0.9892,    1.0000,
-0.2075,   -0.2766,   -0.9892,    1.0000,

如果我通过我的着色器传递B顶点和单位矩阵,它会在视口中间渲染一个小矩形。但是,如果我将A顶点和M矩阵传递给它,它就不会渲染任何内容。

发生了什么事?

3 个答案:

答案 0 :(得分:0)

您使用的数学库可能不会使用与GLSL相同的矩阵顺序。尝试在将矩阵M传递给着色器之前对其进行转置。

答案 1 :(得分:0)

问题是顶点着色器完成后的gl_Position经过裁剪,在那里它与范围[-W W]进行比较并且如果gl_Position超出该范围则被剪裁(未绘制)。

如果将A * M乘以并将结果设置为gl_Position,则给定使用W坐标的矩阵将为-301(负数),这将反转削波比较。

在进行乘法之前,尝试将矩阵M乘以-1,这将产生与将矩阵B乘以单位矩阵相同的结果。

来自“Red Book”:

  

避免使用负w顶点坐标和负q纹理坐标。 OpenGL可能无法正确剪切此类坐标,并且在对由此类坐标定义的图元进行着色时可能会出现插值错误。

答案 2 :(得分:0)

问题在于wz单元格中的-1,三角形以相反方向的法线结束,因为它们是单侧的,所以它们没有绘制。我通过将M改为此来解决了这个问题:

0.4170         0         0         0
     0    0.5560         0         0
     0         0    1.2220    1.0000
     0         0 -444.4440         0

我还改变了z列的符号(实际上是矩阵被转置后的行),以便在z轴上保持-1为近和+1。