How to texture a shape so that texture borders are on geometry bounding box borders?

I generate some shapes with THREE.Shape (shapes that looks like plane with slightly border modification). Then, I extrude with THREE.ExtrudeGeometry, and try to set uvs like this:


  const uvAttribute = geometry.attributes.uv;
  let min = Infinity,
    max = 0;

  //find min max
  for (var i = 0; i < uvAttribute.count; i++) {
    const u = uvAttribute.getX(i);
    const v = uvAttribute.getY(i);
    min = Math.min(min, u, v);
    max = Math.max(max, u, v);

  //map min map to 1 to 1 range
  for (var i = 0; i < uvAttribute.count; i++) {
    let u = uvAttribute.getX(i);
    let v = uvAttribute.getY(i);

    // do something with uv
    u = THREE.MathUtils.mapLinear(u, min, max, 0, 1);
    v = THREE.MathUtils.mapLinear(v, min, max, 0, 1);

    // write values back to attribute
    uvAttribute.setXY(i, u, v);

  geometry.attributes.uv.needsUpdate = true;

After that, I just load the texture and put it on my geometry, here is what I have; you can see 6 geometry on this pictures (there is more on the left but don’t mind):

enter image description here

On the horizontal axis, this is what I want, the borders of the texture are on the border of the “bounding box” of the plane (some planes can be triangles).

But I can’t get the texture to have the same effect on the perpendicular axis (at least I want to have the top texture border on the top geometry border).

I’ve tried to set the texture repeat to [boundingBox.width / texture.width, boundingBox.height / texture.height], but this give me some strange result.

    const texture = loader.load(

    texture.wrapS = THREE.RepeatWrapping;
    texture.wrapT = THREE.RepeatWrapping;
    // 1024 is the width/height of the uv_grid_opengl
    texture.repeat.set(width / 1024, height / 1024);

enter image description here

If I use PlaneGeometry instead of my custom Shape + ExtrudeGeometry, I have a proper and closer results from what I want (with the RepeatWrapping set):

enter image description here