# Normals not rotated correctly

While rendering a cube to the gbuffer (diffuse, normal, depth) I noticed something odd when applying rotations. I build a world matrix for the cube as follows:

``````Yaw = Yaw % MathUtil.PI2;
Pitch = Pitch % MathUtil.PI2;
Roll = Roll % MathUtil.PI2;

Matrix4 s = Matrix4.Scale(Scale);
Matrix4 t = Matrix4.CreateTranslation(Position);

Matrix4 rotY = Matrix4.CreateRotationY(Yaw);
Matrix4 rotX = Matrix4.CreateRotationX(Pitch);
Matrix4 rotZ = Matrix4.CreateRotationZ(Roll);

return s * rotY * rotX * rotZ * t;
``````

If I render the cube with scale 1, position 0,0,0 and no rotations my normals are rendered properly. Applying scale/position does not change this fact.

However, when I apply rotations the normals screw up in some cases.

Nothing wrong in these settings:

• Yaw = Pi/2
• Yaw = Pi
• Pitch = Pi/2
• Pitch = Pi
• Yaw = Pi && Pitch = Pi

But when I apply these rotations:

• Yaw = Pi/2 && Pitch = Pi/2

This happens:

For some reason the normals aren't rotated correctly. I rotate them like this in the vertex shader using the world matrix described above:

``````mat3 WorldMatrix3x3 = mat3(WorldMatrix);
normalWS = vertexNormal_modelspace * WorldMatrix3x3;
``````

And store them in the fragment shader:

``````rtt_normal.xyz = normalWS * 0.5 + 0.5;
``````

I display the normal buffer on the screen like this:

``````color = vec4(abs(texture(gbufferTexture, UV).rgb * 2.0 - 1.0), 1);
``````

What am I missing here?

-

`PI/2` is the magic number that causes gimbal lock. A Euler rotation of that value will disrupt subsequent rotations about another axis, because they have overlain each other. You need to replace

``````Matrix4 rotY = Matrix4.CreateRotationY(Yaw);
Matrix4 rotX = Matrix4.CreateRotationX(Pitch);
Matrix4 rotZ = Matrix4.CreateRotationZ(Roll);
return s * rotY * rotX * rotZ * t;
``````

With something that doesn't suffer from the same problem.

``````Matrix4 rot = Matrix4.CreateFromAxisAngle(axis, angle)
return s * rot * t;
``````
-
Thanks a lot for the great answer and the link. – Korijn May 26 '13 at 17:49