- Home /
How to assign UV coordinates to arbitrary mesh.
I have a wall that is randomly generated.
And I need to assign a UV to it. I need any texture I apply to have a constant tile across the wall. Am I going to have to work out magnitudes between vertexes? What's the easiest way to accomplish this?
"work out magnitudes between vertexes": Yes.
An easy version takes maybe two lines of code. Just copy XZ distance-so-far directly into V (UV's will gladly go past 1, tiling.) Later, multiply by a scale-factor.
"Am I going to have to work out magnitudes between vertexes"
Yes. You are going to have to work out everything.
Answer by aldonaletto · May 16, 2013 at 03:50 PM
If you just want to have a constant 1:1 aspect along each segment, things are easier. If you have to ensure continuity from one segment to the next, then you must also set the uv offset and keep track of the current position when generating new segments.
Supposing that you have just calculated the four vertex of a new segment in variables v1 to v4, where v1 is the top-left vertex, v2 is top-right, v3 is bottom-right and v4 is bottom-left, their corresponding uv coordinates can be calculated in variables uv1 to uv4 as follows:
...
var segW = Vector3.Distance(v1, v2); // calculate segment width
var segH = Vector3.Distance(v1, v4); // calculate segment height
var rightX: float = segW/segH; // calculate right X coordinate
uv1 = Vector2(0,1); // uv relative to the top-left vertex
uv2 = Vector2(rightX,1); // uv relative to the top-right vertex
uv3 = Vector2(rightX,0); // uv relative to the bottom-right vertex
uv4 = Vector2(0,0); // uv relative to the bottom-left vertex
...
If you need continuity, then a curX member variable must be kept and updated after generating each new segment:
var curX: float = 0; // define curX outside any function
...
var segW = Vector3.Distance(v1, v2); // calculate segment width
var segH = Vector3.Distance(v1, v4); // calculate segment height
var rightX: float = curX + segW/segH; // calculate right X coord
uv1 = Vector2(curX,1); // uv relative to the top-left vertex
uv2 = Vector2(rightX,1); // uv relative to the top-right vertex
uv3 = Vector2(rightX,0); // uv relative to the bottom-right vertex
uv4 = Vector2(curX, 0); // uv relative to the bottom-left vertex
// update curX to the next wall segment. Use only the fractionary
// part, since big uv values may cause visible artifacts due to
// the limited precision used in shaders
curX = rightX % 1;
...
"and keep track of the current position when generating new segments"
Hey Aldo wot up. Just for the record: i've often found it better in practice to do it statelessly, each "piece of wall" (or whatever) just goes back to whatever the starting point is and figures out for itself, there and then, what it should be.
so, in practice there might be a line of code: "my left hand start = add up lengths of all pieces left of me"
it's extremely simple. very likely they're in a list or something ...... so it's absolutely trivial.
"Use only the fractionary
// part...
curX = rightX % 1;
" Don't forget if a segment is longer than the texture it needs to be more than 1 delta
Good point: I assumed here that the wall segments are generated sequentially, thus accumulating the segment widths should work as a current left coordinate. If segments aren't generated sequentially, this will fail miserably!
And yes, the right X may be greater than 1.0: that's why the module is applied only when updating curX, which is the next left coordinate. This way, for each segment the left X is in the range 0..1, while the right X may extend to any value; when calculating the left X for the next segment, only the frac part is taken into account.
Your answer
Follow this Question
Related Questions
How to set up UV for lightmaps for generated meshes? 4 Answers
Mesh.uv is out of range 1 Answer
Mesh building changes in Unity 3.5.6 0 Answers
stretched UV map in generated mesh 0 Answers
Don't we love roads? 0 Answers