I've got set of vertices, and would like to calculate their UV coordinates by projecting them by a given normal. Similar to what "planar mapping" does in 3ds max.

Another way of looking at it is that I want to flatten the vertex positions from a given normal direction, so that I can simply use their X & Y (or X & Z depending on your preference) coordinates as UV coordinates.

I'm thinking it's a simple matter of a mathematical Vector function, basically rotating vertex positions along the normal, but I can't figure out the math behind it. I'm using C# and XNA, so I've got Vector3, Matrix and Quaternions. Preferably as cheap as possible.

Any help?

  • \$\begingroup\$ Nice that @DMGregory's answer has solved your problem. Will you be able to share the C# code for this? Thanks in advance \$\endgroup\$ Jul 10 '19 at 17:37

First you construct two basis vectors perpendicular to your projection axis P.

Because of the Hairy Ball Theorem, there's no standard & completely continuous way to do this, but we can hack around it something like...

U = cross(P, (0, 0, 1));
if (dot(U, U) < 0.001)
    U = (1, 0, 0);

V = normalize(cross(P, U));

Then for each point Q in your mesh, you can construct a u,v coordinate by projecting it onto each basis vector:

uv = (dot(Q, U), dot(Q, V)) * uvscale;

With a scalar multiply if you want your uvs larger/smaller.

This is equivalent to a matrix multiplication, where U and V are the first two rows of a rotation matrix, and the third row P is omitted.

I may have gotten the handedness wrong above, so if your uvs come out mirrored from what you expect, flip the arguments to cross()


You must log in to answer this question.

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