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:
geometry.computeBoundingBox();
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;
geometry.computeVertexNormals();
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):
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(
"https://threejs.org/examples/textures/uv_grid_opengl.jpg"
);
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);
Edit:
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):