Dear Myth Xenodo,
Firstly, from what I see the problem in your code is all about texture mapping. I believe the UV coordinates are not generated for a shapegeometry or extrude geometry. You have to take care of generating the UV coordinates for your shape. Then the image will start showing up. Currently all the uv coordinates are assigned to 0,0.
Secondly, to achieve the effect based on the example URL you have provided. You need to approach it differently. One way to achieve this by having two different threejs scenes rendered to a single canvas as an image. However, ensure to move the cameras in these scenes with your logic to paint the canvas image. There will be a third scene with a custom shapegeometry with proper uv coordinates that will paint the image in the canvas. Hence, you paint the canvas dynamically it is going to reflect in the texture of the custom shapegeometry you are creating.
I will show you how to update the uv coordinates for your shapegeometry below
projected2DCoordinates(coordinate: Vector3, normal: Vector3): Vector2{
function projectOnPlane(point: Vector3, u: Vector3, v: Vector3): Vector2{
return new Vector2(point.dot(u), point.dot(v));
}
function getUVVectors(normal: Vector3): Array<Vector3>{
let u: Vector3;
let v: Vector3;
let dot: number = Math.abs(FORWARD.dot(normal));
let dot2: number = Math.abs(RIGHT.dot(normal));
/**
* If the angle between FORWARD and NORMAL is 0 degrees
* then FORWARD is the NORMAL itself, in that case
* use the orthogonal vectors RIGHT and cross(RIGHT, FORWARD)
*/
if(dot == 1){
return [RIGHT.clone(), RIGHT.clone().cross(normal)];
}
/**
* If the angle between RIGHT and NORMAL is 0 degrees
* then RIGHT is the NORMAL itself, in that case
* use the orthogonal vectors FORWARD and cross(FORWARD, FORWARD)
*/
else if(dot2 == 1){
return [FORWARD.clone(), FORWARD.clone().cross(normal)];
}
if(dot < 0.2 || dot > 1.0-1e-6){
u = RIGHT.clone().projectOnPlane(normal).normalize();
}
else{
u = FORWARD.clone().projectOnPlane(normal).normalize();
}
v = u.clone().cross(normal).normalize();
return [u, v];
}
let [u, v] = getUVVectors(normal);
return projectOnPlane(coordinate, u, v);
}
function textureDefinitionShapeGeometry() {
let dim: Vector3 = dimension of your shapegeometry computed from bounding box;
let inverseDim: Vector3 = new Vector3(1 / dim.x, 1 / dim.y, 1 / dim.z);
shapeGeometry.groups.forEach((group: any) =>{
for (i = group.start; i < (group.start + group.count); i+= 3){
a.fromBufferAttribute(positionAttribute, i);
b.fromBufferAttribute(positionAttribute, i + 1);
c.fromBufferAttribute(positionAttribute, i + 2);
ab = b.clone().sub(a);
bc = c.clone().sub(b);
ca = a.clone().sub(c);
ac = c.clone().sub(a);
normal = ab.clone().cross(ac).normalize();
a2D = projected2DCoordinates(a, normal);
b2D = projected2DCoordinates(b, normal);
c2D = projected2DCoordinates(c, normal);
dim2D = projected2DCoordinates(dim, normal);
inverseDim2D = projected2DCoordinates(inverseDim, normal);
a2D.multiply(inverseDim2D);
b2D.multiply(inverseDim2D);
c2D.multiply(inverseDim2D);
uvAttribute.setXY(i, Math.abs(a2D.x), Math.abs(a2D.y));
uvAttribute.setXY(i + 1, Math.abs(b2D.x), Math.abs(b2D.y));
uvAttribute.setXY(i + 2, Math.abs(c2D.x), Math.abs(c2D.y));
}
});
}
I hope this will solve your problem of UV coordinates for your custom shape. Doing the effect is a different story altogether based on the strategy I proposed earlier. Feel free to ask for more explanation if you need it.
Regards,
#0K