Automatic creation of UV coordinate algorithms

I am writing my own uv editor for my tool, and I am trying to include as many algorithms as possible for forecasts. I need to take an arbitrary grid and make uv coordinates for each vertex.

So far I have had a flat and minimal square map.

I would like to include more, for example, tri-planar, cylinder, spherical, but it is very difficult for me to find information for the execution of algorithms. The tri-planar seems to create color, but I need to get everything in UV coordinates.

Help would be greatly appreciated!

+6
source share
3 answers

Tri-planar

Forget it: this is not a projection algorithm (an algorithm that gives you UV coordinates), and you cannot get UV coordinates from it. This is a rendering algorithm that gives you the color obtained by mixing the color that you would get with each XYZ planar projection separately.

Cylindrical, spherical

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

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

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

Cubic

First, you need to determine which “projection face" you assign to each face of your grid. I call the projection faces X, -X, Y, -Y, Z, and -Z, as in the figure below (where I assume that the X, Y, and Z axes are Red, Green, and Blue, respectively):

enter image description here

To do this, you simply discover which normal coordinate (nx, ny, nz) has the largest absolute value and assigns its face to this axis and sign. For instance:

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

Then, as soon as you know which side of the projection you assign each face of your grid to, 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 convert this value uv_temp ∈ [0,1] x [0,1] to the uv value included in the smaller square, as shown in image A above. For example, if you applied the projection "X", then you want to get uv ∈ [2/3, 3/3] x [2/4, 3/4], then you will do:

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

Finally, the last step is to remember to duplicate the UV vertices that belong to two faces with different flat projections (borders between different colors in the image). Indeed, some grid vertices can (and should in most cases) be split into several positions in the UV map to give decent results.

+17
source

Cubic matching

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

First find the Reflected Vector R = 2 (N point 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 

After assigning sc, tc and ma, the coordinates (s, t) for this face can be calculated using 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; } 

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

Spherical, cubic and parabolic comparisons of the environment http://www.unc.edu/~zimmons/cs238/maps/environment.html

OP, please share your least-squares Conestal Mapping algorithm to generate UV coordinates. Thanks.

+2
source

Source: https://habr.com/ru/post/953003/


All Articles