OpenGL ES 2.0: matrix multiplication problem
I'm trying to draw a quadrilateral using OpenGL ES 2.0. My vertex shader looks like this:
uniform mat4 mvp;
attribute vec4 position;
attribute vec4 color;
varying vec4 colorVarying;
void main()
{
gl_Position = mvp * position;
colorVarying = color;
}
If I use these vertices:
-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
and this matrix (in column-major order, as are all following matrices):
0.5,0,0,0,
0, 1,0,0,
0, 0,1,0,
0.5,0,0,1
the quad covers the right half of the viewport. Indeed, if I multiply those two matrices I get the vertices
0, -1, 0, 1,
1, -1, 0, 1,
0, 1, 0, 1,
1 , 1, 0, 1,
and if I use those vertices and an identity matrix, I get the same result. So it seems that the multiplication is done correctly.
Now, if I multiply these vertices (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,
by this matrix (M):
0.4170 0 0 0
0 0.5560 0 0
0 0 -1.2220 -1.0000
0 0 444.4440 0
I get these vertices (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,
and if I pass my shader the B vertices and an identity matrix, it renders a small rectangle in the middle of the viewport. But if I pass it the A vertices and the M matrix, it renders nothing.
What's going on?
The problem is that gl_Position after the vertex shader completes goes through clipping where it is compared against the range [-W W] and clipped ( not drawn ) if it gl_Position falls outside of that range.
IF you multiply A * M and set the result to gl_Position, then given the matrices you are using the W coordinate will be -301, a negative number, which will invert the clipping comparison.
Try multiplying the matrix M by -1 before doing the multiplication, that should yield the same results as multiplying matrix B by the identity matrix.
From the "Red Book":
Avoid using negative w vertex coordinates and negative q texture coordinates. OpenGL might not clip such coordinates correctly and might make interpolation errors when shading primitives defined by such coordinates.
The math library you are using might not use the same matrix order as GLSL. Try transposing your matrix M before passing it to the shader.
The problem was that with that -1 in the wz cell, the triangles ended up with their normal in the opposite directions, and since they are one-sided they were not drawn. I solved the problem by changing M to this:
0.4170 0 0 0
0 0.5560 0 0
0 0 1.2220 1.0000
0 0 -444.4440 0
I also changed the sign of the z column (actually row since the matrix is transposed) in order to keep -1 as near and +1 as far on the z axis.
精彩评论