How to fix UV problem on ExtrudeGeometry

Hi there,

I created a component that creates a ExtrudeGeometry by giving it a width and a angle value. That works so far. As you can see in the Codesandbox the uv messes up when an angle is applied obviously.
My goal is to fix that so the uv is always straight like in the image provided (from Blender):


Any advice would be helpful, thanks!

At its core, the phenomenon you are observing is very much related to an issue in the context of rendering quadrilaterals, which are (internally) subdivided into two triangles which are rendered separately. See an extensive discussion about it in this thread. Spoiler alert: so far I’m not aware of a solution.

To show, that we are indeed observing the same phenomenon, I took a screenshot from your codesandbox and overlayed the diagonal as a white line:

2 Likes

I think you are correct, but I think if OP wants what they see in blender, it could still be done. notice the slanted part on OPs screenshot is clipping, so that mapping wouldn’t require texture stretching.

You could do a cylindrical UV unwrap on the resulting geometry.

I understand what you mean but the actulal problem i mean is on the arc. Thats texture stretching like in this video (Blender, shot from above):

It makes sense that the texture stretches at this point because of the angle.
In blender i just mark my seams at both arcs and on a connection edge and its unwrapped correct (atleast for me correct). Is this also possible in threejs?

My first idea was to somehow use the uv of the geometry without the angle but i could not make it work. With cylindrical uv unwrap do you mean the same as i did in blender?

Yeah but doing it programatically. Looping through the resulting vertices, and the uvs, and regenerating the UVs from the atan of the vertex x/y, and z.

// Update the UVs
  for (let i = 0; i < uvAttribute.count; i++) {
    const u = i * 2 + 0; // u-coordinate index
    const v = i * 2 + 1; // v-coordinate index

    // Check if the vertex is at the end of the extrusion
    if (uvAttribute.array[v] >= 0 && uvAttribute.array[v] <= 0.01) {
      // Adjust the v-coordinate based on the u-coordinate and the angle
      // console.log("u; " + uvAttribute.array[u], "v: " + uvAttribute.array[v]);

      uvAttribute.setY(i, uvAttribute.array[v] + uvAttribute.array[u] * tanAngle);
    }
  }

i tried like that but it does not work… or did you mean something else?

not quite. I’m saying use the atan2 of the x and y of the corresponding position, as the U, and setting the V to the z of the position.

Would something as simple as this be OK for you? (added lines 43 and 44):

if (geometry.attributes.normal.getZ(i) == 0)
   uvAttribute.setY(i, vertices[i2]);
5 Likes

I hate to burst your bubble, but the same issue with mapping quadrilaterals is just as visible in Blender, too: => screenshot taken from your blender video.

Be aware, that the arc portion of yout path is, after extrusion, approximated by a number of horizontal, rather thin quadrilaterals as well, one marked as a blue continuous line. Those quadrilaterals are subject to the same quadrilateral- into-triangles subdivision as on the flat side of your shape. Again, the white lines highlight the diagonals of those quadrilaterals. Note, how the leftmost jag of the pattern’s vertical lines always matches the intersection point with the white diagonal, highlighted by a red ellipsis:

[Edit:]
On a related note, if you increase the level of subdivisions of your shape to an arbitrarily high enough level, the problem may (will!) become unoticeable (while still be present).

2 Likes

@kalabedo

This is what I meant:

erg edit codepen lost my change 1 sec…
OK here:
https://codesandbox.io/p/sandbox/extrudeuv-forked-ght3pz?file=%2Fsrc%2FExtrudeTest.jsx%3A43%2C1-44%2C37

Edit2: @PavelBoytchev 's might actually be better/simpler. but yeah… I did the atan2 cylindrical unwrap. Take your pick…

3 Likes

Exactly what i was looking for, thanks. I would’nt have thought it was that simple wow!

You are right! I noticed if i change the extrudeSteps that this behaviour minimizes. I noticed that in blender there is the same problem but i was referring to the unwrapped object at the end of the video!

1 Like

Thanks thrax for this solution!!
I marked Pavels answer as solution, because it is simpler and how i use it now.
Anyways your answer is a good resource for me to understand the cylindrical unwrap! :blush:

1 Like