0

I have the following (working) code in a GLSL shader:

vec3 normal = vec3(u_mvMatrix * vec4(0.0,0.0,1.0,0.0));//normal in eye space (no scaling in u_mvMatrix).

However, since what I need is just the z direction of the u_mvMatrix, which of the following lines is equivalent to the line above:

vec3 normal = u_mvMatrix[2].xyz;

or:

vec3 normal = vec3(u_mvMatrix[0].z,u_mvMatrix[1].z,u_mvMatrix[2].z);

?

Thanks in advance for your help!

4

1 回答 1

0

OpenGL matrices are column-major by default.

You can make them row-major in GLSL with a layout qualifier (e.g. layout (row_major) uniform mat4 u_mvMatrix;). Note that pre-multiplication of a row-major matrix is the same as post-multiplication of a column-major matrix, so this is a true statement:

(mat * vec) == (vec * transpose (mat))

In the fixed-function pipeline when OpenGL does a matrix multiply, it is always column-major and post-multiplied. Direct3D is row-major and pre-multiplied. In the programmable pipeline you have full control over the matrix notation and whether you pre- or post-multiply.

Getting back to your question, in this example you are post-multiplying (the matrix is on the l-hand side of the * operator) a column-major matrix. The correct equivalence is therefore vec3 normal = u_mvMatrix [2].xyz;

For a lengthy article that does a decent job explaining what I just wrote, see this site.

于 2013-08-14T21:28:27.393 回答