I have a custom geometry with a texture like so:
My original image is:
Is it possible somehow to morph the texture so that every pixel is contained on the geometry? You can see that the 2 blue posts are cut off from the right hand side. I’d like it so that 100% of the original image is on the geometry, so in this example the bottom half would be squished a bit.
If that makes any sense at all.
I have zero photoshop skills but I’m wanting it to warp kinda like this:
In order to create the above, using the SVGLoader, I take a path and render a geometry like so:
const renderSVG = (svg) => {
const svgGroup = new THREE.Group();
svgGroup.scale.y *= -1;
const svgData = loader.parse(svg);
svgData.paths.forEach((path) => {
const shapes = SVGLoader.createShapes(path);
shapes.forEach((shape) => {
const geometry = new THREE.ShapeGeometry( shape );
setUV(geometry);
const mesh = new THREE.Mesh( geometry, fillMaterial );
svgGroup.add( mesh );
});
});
const box = new THREE.Box3().setFromObject(svgGroup);
const size = box.getSize(new THREE.Vector3());
const yOffset = size.y / -2;
const xOffset = size.x / -2;
// Offset all of group's elements, to center them
svgGroup.children.forEach((item) => {
item.position.x = xOffset;
item.position.y = yOffset;
});
svgGroup.rotateX(-Math.PI / 2);
scene.add(svgGroup);
};
The setUV function is required in order to apply a texture (correct me if I’m wrong), I’m pretty sure prisoner849 wrote this:
const setUV = (geometry) =>{
let pos = geometry.attributes.position;
let b3 = new THREE.Box3().setFromBufferAttribute(pos);
let size = new THREE.Vector3();
b3.getSize(size);
let uv = [];
let v3 = new THREE.Vector2();
for(let i = 0; i < pos.count; i++){
v3.fromBufferAttribute(pos, i);
v3.sub(b3.min).divide(size);
uv.push(v3.x, v3.y);
}
geometry.setAttribute("uv", new THREE.Float32BufferAttribute(uv, 2));
}