我正在尝试使用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矩阵传递给它,它就不会渲染任何内容。
发生了什么事?
答案 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。