17

I'm writing my own uv editor for a tool of mine, and I'm trying to incorporate as many algorithms as I can for projections. I need to take an arbitrary mesh, and make uv coordinates for each vertex.

So far, I have planar, and Least Squares Conformal Map.

I'd like to incorporate more, such as tri-planar, cylinder, spherical, but I'm having a very difficult time locating the information to perform the algorithms. The tri-planar appear to generate a color, but I need to get everything in UV coordinates.

Help would be very appreciated!!

Mary Ellen Bench
  • 589
  • 1
  • 8
  • 28
  • 1
    You can also check out [planar parameterization methods](http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Surface_mesh_parameterization/Chapter_main.html) implemented by the CGAL guys – Arun R Sep 04 '13 at 12:02

3 Answers3

31

Tri-planar

Forget about it: it is not a projection algorithm (an algorithm that gives you UV coordinates), and there is no way you can get UV coordinates out of it. It is a rendering algorithm that gives you a color obtained by blending what color you would obtained using each X-Y-Z planar projections separately.

Cylindrincal, Spherical

Like planar, those are very simple projection algorithms that give you a UV value directly from a XYZ value, without taking into account the connectivity with other vertices.

  • For cylindrical: convert (x, y, z) into Cylindrical Coordinates (ρ, φ, z), and use as UV coordinates u = φ and v = z
  • For spherical: convert (x, y, z) in Spherical Coordinates (r, θ, φ), and use as UV coordinates u = θ and v = φ

Of course, you can switch the roles of X, Y and Z to project using a different axis, or perform some translation/rotation/scaling to have more control (the same way that you can control the size and orientation of the plane you use for the planar projection).

Cubic

First, you need to determine to which "projection face" you assign each face of your mesh. I name the projection faces X, -X, Y, -Y, Z and -Z as in the figure below (where I assume the X, Y, and Z axis have respectively the colors Red, Green, and Blue):

enter image description here

For this, you simply find which coordinate of the normal (nx, ny, nz) has the greatest absolute value, and assign it to the face corresponding to this axis and sign. For instance:

  • if n = (0.8, 0.5, 0.3), then the corresponding face is X (|nx| is the greatest and nx is positive)
  • if n = (0.3, 0.8, 0.5), then the corresponding face is Y (|ny| is the greatest and ny is positive)
  • if n = (0.3, -0.8, 0.5), then the corresponding face is -Y (|ny| is the greatest and ny is negative)

Then, once you know to which projection face you assign every face of your mesh, you can apply the corresponding planar projection to the vertices around this face to get a temporary value (u_temp, v_temp) ∈ [0,1] x [0,1].

The next step is to transform this value uv_temp ∈ [0,1] x [0,1] into a value uv included in the smaller square as represented in the image A above. For instance, if you applied the projection "X", then you want uv ∈ [2/3, 3/3] x [2/4, 3/4], then you would do:

u = 2./3. + u_temp/3.;
v = 2./4. + v_temp/4.; 

Finally, the last step is not to forget to duplicate the UV vertices that belong to two faces with different planar projection (the borders between the different colors on the picture). Indeed, some vertices of the mesh can (and should in most cases) be split in several positions in the UV map to give decent results.

Boris Dalstein
  • 7,015
  • 4
  • 30
  • 59
  • That's very helpful! The only other one I was wondering about is the "cubic projection". How do you know based on the normals, which face to assign it to and where to put the uvs? Like this:http://softimage.wiki.softimage.com/xsidocs/ft0a0491.jpg – Mary Ellen Bench Sep 04 '13 at 04:45
  • Thanks much, I suspected that way, with the normals, but I wasn't 100% sure. One final question, then I'll mark as answer, your help has been much appreciated. When I'm converting between Cartesian and spherical, occasionally I get a phi ( outphi = atan2(y,x) ), where y and x are both 0. How do I correct for this? CartesianToSpherical outrho = sqrt(x*x + y*y + z*z); outphi = atan2(z,(sqrt(x*x + y*y))); outz = atan2(y,x); CartesianToCylindrical outrho = sqrt(x*x + y*y); outphi = atan2(y,x); outz = z; – Mary Ellen Bench Sep 04 '13 at 05:50
  • In the case of x = y = 0, then it means you are at one of the poles of your sphere, which can be anywhere on the top horizontal line if z>0, or on the bottom horizontal line if z<0 (it's like in the classical world map representation: the North Pole is everywhere on the top line). So it is up to you to decide which of these available point you use. I would do the simplest: choose phi = 0. – Boris Dalstein Sep 04 '13 at 06:00
  • When I set to = 0, I get http://gyazo.com/5260dbcdf55448e40adc04c203462fb4 (there's a clear line going across those poles). Was there a better way to do that part? – Mary Ellen Bench Sep 04 '13 at 06:24
  • @MaryEllenBench This happens because you didn't "cut" your mesh at phi = 0. If the equator of your sphere is made of 5 vertices that have the U-values 0, 0.2, 0.4, 0.6 and 0.8, then the last face linking 0.8 to 0 will cover the whole texture in backward order, resulting in the discontinuities you see. This is why you have to duplicate some of the vertices, in this case the ones with phi = 0, so you have now 6 UV-vertices, at 0, 0.2, 0.4, 0.6, 0.8 and 1. This may be tricky to implement, but you should be able to figure it out by yourself, it definitely goes out of the scope of a SO answer ;-) – Boris Dalstein Sep 04 '13 at 06:40
3

Cubic Mapping

The standard method of doing this, based on a (rx, ry, rz) vector is to first look up some values in a table. These values are used for the (s,t) (or (u,v)) texture coordinate per vertex.

First find the Reflected Vector R = 2(N dot V)N - V, Where V = Vertex, N = Normal , R Reflected Vector(rx,ry,rz)

                      major axis 
                      direction      sc     tc     ma 
                      ---------      ---    ---    -- 
                      +rx            -rz    -ry    rx 
                      -rx            +rz    -ry    rx 
                      +ry            +rx    +rz    ry 
                      -ry            +rx    -rz    ry 
                      +rz            +rx    -ry    rz 
                      -rz            -rx    -ry    rz 

Once sc, tc, and ma has been assigned values, (s,t) coordinates for that face can be calculated with the following formulas.

if((rx >= ry) && (rx  >= rz)) 
{ 
sc = -rz; 
tc = -ry; 
ma = fabs(rx);  //absolute value
s = ((sc/ma) + 1) / 2; 
t = ((tc/ma) + 1) / 2; 

cout << "+rx (" << s << "," << t << ")" << endl; 
} 

  if((rx <= ry) && (rx  <= rz)) 
{ 
sc = +rz; 
tc = -ry; 
ma = fabs(rx); 
s = ((sc/ma) + 1) / 2; 
t = ((tc/ma) + 1) / 2; 

cout << "-rx (" << s << "," << t << ")" << endl; 
} 

if((ry >= rz) && (ry >= rx)) 
{ 
sc = +rx; 
tc = +rz; 
ma = fabs(ry); 
s = ((sc/ma) + 1) / 2; 
t = ((tc/ma) + 1) / 2; 

cout << "+ry (" << s << "," << t << ")" << endl; 
} 

if((ry <= rz) && (ry <= rx)) 
{ 
sc = +rx; 
tc = -rz; 
ma = fabs(ry); 
s = ((sc/ma) + 1) / 2; 
t = ((tc/ma) + 1) / 2; 

cout << "-ry (" << s << "," << t << ")" << endl; 
} 

if((rz >= ry) && (rz >= rx)) 
{ 
sc = +rx; 
tc = -ry; 
ma = fabs(rz); 
s = ((sc/ma) + 1) / 2; 
t = ((tc/ma) + 1) / 2; 

cout << "+rz (" << s << "," << t << ")" << endl; 
} 

if((rz <= ry) && (rz <= rx)) 
{ 
sc = -rx; 
tc = -ry; 
ma = fabs(rz); 
s = ((sc/ma) + 1) / 2; 
t = ((tc/ma) + 1) / 2; 

cout << "-rz (" << s << "," << t << ")" << endl; 
} 

Reference http://www.unc.edu/~zimmons/cs238/maps/cubeind.html

Spherical, Cubic, and Parabolic Environment Mappings http://www.unc.edu/~zimmons/cs238/maps/environment.html

OP would you please share your Least Squares Conformal Mapping algorithm for generating UV coordinates. Thank you.

DeJean
  • 31
  • 3
2

You should start from the siggraph course Mesh Parameterization: Theory and Practice then look into the cited papers for details on the algorithms you're implementing

a.lasram
  • 4,371
  • 1
  • 16
  • 24
  • I'm looking for a more concise set of "pseudocode"/algorithms if possible, of the simpler ones. Tri-planar for example, for converting the colors to uvs. I don't see that there. – Mary Ellen Bench Sep 02 '13 at 21:19