4
\$\begingroup\$

I am attempting to transform the components of a mesh directly using a 4x4 matrix. This is working for the vertex positions, but it is not working for the normals (and probably not the tangents either).

Here is what I have:

// Transform vertex positions - Works like a charm!
vertices = mesh.vertices;
for (int i = 0; i < vertices.Length; ++i)
    vertices[i] = transform.MultiplyPoint(vertices[i]);

// Does not work, lighting is messed up on mesh
normals = mesh.normals;
for (int i = 0; i < normals.Length; ++i)
    normals[i] = transform.MultiplyVector(normals[i]).normalized;

// Tangents?? I really do not understand these guys
tangents = mesh.tangents;
for (int i = 0; i < tangents.Length; ++i) {
    Vector4 temp = transform.MultiplyVector(tangents[i]).normalized;
    temp.w = tangents[i].w;
    tangents[i] = temp;
}

Note: The input matrix converts from local to world space and is needed to combine multiple meshes together.

\$\endgroup\$
5
  • \$\begingroup\$ If your normal matrix does not have uniform scale (ie same amount of scale in x,y,z directions), then it will screw up the normals. \$\endgroup\$
    – bobobobo
    Nov 26, 2012 at 23:11
  • \$\begingroup\$ @bobobobo Should I have a different matrix for normals then? The built-in Unity Mesh.CombineMeshes seems to work fine with the same input matrix. But obviously it could be creating a normal matrix or something. Are you suggesting that I should be using transform.inverse.transpose.MultiplyVector instead? \$\endgroup\$
    – Lea Hayes
    Nov 26, 2012 at 23:14
  • 2
    \$\begingroup\$ Definitely don't do it like that! You'll be inverting the matrix for every vector you need to multiply. Try creating a second matrix normalMatrix = transform.inverse().transpose() and see if that solves your problem. A tangent is just a vector that "grazes" the surface. \$\endgroup\$
    – bobobobo
    Nov 27, 2012 at 1:03
  • 1
    \$\begingroup\$ @bobobobo: you should probably write that as an answer. \$\endgroup\$ Nov 27, 2012 at 1:35
  • \$\begingroup\$ Awesome that seems to work! The lighting behaves a little differently from the original meshes in that they detect the light at different stages. But the normals appear to behave correctly and I am guessing that the tangents are also (though the w component might be messed up)... cheers! \$\endgroup\$
    – Lea Hayes
    Nov 27, 2012 at 1:41

1 Answer 1

3
\$\begingroup\$

If your normal matrix does not have uniform scale (ie same amount of scale in x,y,z directions), then it will screw up the normals.

Try creating a second matrix normalMatrix = transform.inverse().transpose() and see if that solves your problem. A tangent is just a vector that "grazes" the surface.

\$\endgroup\$
0

You must log in to answer this question.

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