0
\$\begingroup\$

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.

Normals with no transformation

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:

Normals with transformation Yaw = Pi/2 && Pitch = Pi/2

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?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

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;
\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .