Issues with Z-axis rotation matrix in glsl shader

匿名 (未验证) 提交于 2019-12-03 01:32:01

问题:

I've recently began putting together an opengl es 1.1/2.0 2D pipeline from the ground up (iPhone only). This pipeline is intended to be used by engineers with no 3D math experience.

Commented out are the X and Y axis rotation matrices that produce the exact results they should. The Z rotation matrix seems to do nothing.

VERTEX SHADER

//THESE WORK /* highp mat4 rotationMatrix = mat4(1.0, 0.0, 0.0, 0.0,                                  0.0, cos(angle), -sin(angle), 0.0,                                  0.0, sin(angle), cos(angle), 0.0,                                  0.0, 0.0, 0.0, 1.0);   highp mat4 rotationMatrix = mat4(cos(angle), 0.0, sin(angle), 0.0,                                  0.0, 1.0, 0.0, 0.0,                                  -sin(angle), 0.0, cos(angle), 0.0,                                  0.0, 0.0, 0.0, 1.0);  */  //THIS DOESN'T WORK >:( highp mat4 rotationMatrix = mat4(cos(angle), -sin(angle), 0.0, 0.0,                                      sin(angle), cos(angle), 0.0, 0.0,                                      0.0, 0.0, 1.0, 0.0,                                      0.0, 0.0, 0.0, 1.0);    gl_Position = a_position; gl_Position *= rotationMatrix; 

Since this will be for 2D rendering and handed to engineers without 3D experience, I would prefer to stay away from passing in a MVP matrix and just push the basic scale, rotation and translation variables (and skip writing a partial matrix lib for the 10th time).

It's been a while since I've tangled with matrix math and shaders, so I'm hoping its a small error.

Thanks for your help!

EDIT/UPDATE:

I found at that a post-processing pass was clobbering the angle.

I now find that Z-rotation seems to scale the quad. I remember this being a n00b problem and am looking into it...

I forgot to mention that I have a cheap temp projection Matrix

//s_scalefactor is for retina vs non-retina display  highp mat4 projectionMatrix = mat4( 2.0/(320.0 * s_scalefactor), 0.0, 0.0, -1.0,                                     0.0, 2.0/(480.0 * s_scalefactor), 0.0, -1.0,                                     0.0, 0.0, 1.0, 0.0,                                     0.0, 0.0, 0.0, 1.0);    gl_Position *= projectionMatrix; 

Its cheap hack, but I'm not certain it would stiff a Z rotation.

EDIT #2:

I've also gotten nowhere attempting to use a frustum instead of ortho and calculating the matrix outside of the shader.

回答1:

I had the same problem and it was very, very strange. I was able to resolve it by populating the mat4 structure by using the accessor operators as opposed to using the constructor:

mat4 rotateZ; rotateZ[0].x    = cosAngle; rotateZ[0].y    = negSinAngle; rotateZ[0].z    = 0.0; rotateZ[0].w    = 0.0; rotateZ[1].x    = sinAngle; rotateZ[1].y    = cosAngle; rotateZ[1].z    = 0.0; rotateZ[1].w    = 0.0; rotateZ[2].x    = 0.0; rotateZ[2].y    = 0.0; rotateZ[2].z    = 1.0; rotateZ[2].w    = 0.0; rotateZ[3].x    = 0.0; rotateZ[3].y    = 0.0; rotateZ[3].z    = 0.0; rotateZ[3].w    = 1.0; 


回答2:

The following code performs a translation of the input matrix, moving along the X, Y and Z axis of the input matrix.

typedef float TVec3[3]; typedef float TMat4[16]; void Translate(      TMat4       &mat,    // input matrix     const TVec3 &trans ) // translation vector {     for ( int i = 0; i 

The next function shows how to perform a rotation on the input matrix, around an the X, Y or Z-axis of the input matrix. The direction of rotation is clockwise when looking in the rotation axis direction.

typedef float TMat4[16]; void RotateAxis(      TMat4 &mat,    // input matrix     float  angRad, // roatation angle (radians)     int    axis )  // rotation axis: 0 - X; 1 - Y; 2 - Z  {     const int a0map[3] = { 1, 2, 0 };     const int a1map[3] = { 2, 0, 1 };     const int a0 = a0map[axis];     const int a1 = a1map[axis];     const float sinAng = sin(angRad);     const float cosAng = cos(angRad);      // rotate the matrix     TMat4 tempM;     memcpy( tempM, mat, sizeof(TMat4) );     for ( int i = 0; i 

For the sake of completeness, the function for scaling the input matrix.

typedef float TVec3[3]; typedef float TMat4[16]; void Scale(      TMat4       &mat,    // input matrix     const TVec3 &scale ) // scale factors {     for ( int a = 0; a 

Look at the following example to see how translation and rotation interact together (tested with Firefox, Chrome, Edge, Opera):

pre translate X
pre translate Y
pre translate Z
axis of rotation
post translate X
post translate Y
post translate Z


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!