0
\$\begingroup\$

I have a set of given texture coordinates(u,v coordinates), but they are ranging from (-inf, inf), contradicting the [0,1] convention.

I tried to do a rescaling by value = (value - min) / (mac - min). But if I have a rectangle which composed of two triangles, four vertices. Suppose the u,v coordinates are -0.260944 0.490887 3.619507 0.490887 3.619507 -3.043434 -0.260944 -3.043434

After scaling, the coordinates would be mapped to exact -1 and 1, resulting in wrong texture.

So how should I deal with this kind of texture coordinates?

\$\endgroup\$
  • 1
    \$\begingroup\$ I agree with Tom K's answer in general. However, if you're actually getting values like inf, -inf, NaN or other special case numbers in your coords, that strongly suggests to me that something went wrong when the coords were generated. Is you're reference to (-inf, inf) literal or did you just mean arbitrarily large negative & positive values? \$\endgroup\$ – Pikalek Sep 19 '17 at 16:57
  • \$\begingroup\$ @Pikalek Hi! (-inf, inf) is a "range", not the actual value. I just want to indicate that there are negative coordinates smaller than -1. Sorry for the ambiguity. \$\endgroup\$ – jinglei Sep 20 '17 at 0:50
1
\$\begingroup\$

Texture coordinates that go greater than abs(1) generally are used to specify tiling. So if you have a coordinate (such as in your example) that goes from 3.619507 to -0.260944, then that means that the texture is repeated a bit more than 3.5 times in that distance. Sometimes, certain art packages will give UV coordinates without tiling that are greater than 1. Those would be UV coordinates such as 1.45-1.68. A UV coordinate from 1.45 to 1.68 can be renormalized to 0.45 to 0.68, which is equivalent in most cases.

Going back to your example, you could, in theory, rescale your UV coordinates to be be within the range of -1,1 to by doing the modulus. For example, 3.619507 would become 0.619507, and -3.043434 becomes -0.043434. At each vertex, you would be referencing the same texture coordinate as before, but as the GPU renders the texture across the face of your triangle, it would not repeat, so it would still look different.

//START TLDR
There isn't a great solution for you, your rendering engine either needs to support tiling, or you would have to subdivide your triangle such that you don't have any tiling in the UV coordinates. This subdivision is basically to linearly interpolate your UV coordinates across each edge, and create new vertices with new UV coordinates that don't tile. This can get very complex very quickly. Let's imagine you have a triangle (so it only consists of 3 points). For the purposes of this example, let's assume the U and V coordinates are always the same, that way we'll only talk about a single value for each point. If one point has the UV 3.0, and the other 2 points have the UV 0.0, then we will have to subdivide each edge that has UV coordinates 3.0 and 0.0. So the edge in question would end up being 4 edges instead, one that goes from 0.0 to 1.0, a new one that goes from 1.0 to 2.0, and a final one that goes from 2.0 to 3.0. Each of those would end up getting re-normalized into values from 0-1, so the edge that goes from 1.0 to 2.0 gets normalized into 0.0 to 1.0 again, and the same for the edge that goes from 2.0 to 3.0. Here comes the second problem. While that is only 3 edges, you have 3 edges that are back to back that go from 0.0 to 1.0. The 1.0 point on one edge is the point on the next edge that is 0.0, which means you can't share vertices between the edges. That means that your 0.0 to 3.0 point becomes 6 new vertices (0.0 stays at 0, 1.0 turns into 1.0 and 0.0, 2.0 turns into 1.0 and 0.0, and 3.0 becomes 1.0). Since you were dividing a triangle, you end up with a number of different polygons (think about a line through a triangle. You can end up with either 2 triangles, or you can end up with a triangle and a quad), some of which won't have 3 edges. Those again need to be decomposed into triangles (so your quad becomes 2 triangles). As you can see, the subdivision method is complex.
//END TLDR

In the end, you are trying to render a model that your renderer doesn't natively support, and anything you try to "fix" it is going to result in an approximation. I find it unlikely that your renderer doesn't support tiling, it may just be disabled. If the renderer is set to CLAMP instead of TILE (which is often the case), then any value greater than 1.0 will be clamped to 1.0. Instead, set the renderer to TILE, and you can leave your UV coordinates alone, and everything should work correctly.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the answer. I made a mistake in the question detail. I said the conventional uv coordinates are between [-1,1], then I found it should be [0, 1]. I think when encounter coordinates between [-1,0), I can simply add 1 to get its actual place on the texture? (e.g -0.6 -> 0.4) \$\endgroup\$ – jinglei Sep 20 '17 at 2:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.