Skip to content Skip to sidebar Skip to footer

Texturing A Cylinder In Three.js

I'm looking after this for a long time now. I just can't find any solution, anywhere. I'm trying to apply 3 different textures on a cylinder (2 caps, and side) But I have absolute

Solution 1:

[edit] Three cylinders didn't work since the cap UVs are bogus. You need to roll your own cap geometries. Not a lot of work, just annoying. Here's how to do an uncapped cylinder with custom caps:

varcoin_sides_geo=newTHREE.CylinderGeometry( 10.0, 10.0, 1.0, 100.0, 10.0, true );
varcoin_cap_geo=newTHREE.Geometry();
varr=10.0;
for (var i=0; i<100; i++) {
  vara= i * 1/100 * Math.PI * 2;
  varz= Math.sin(a);
  varx= Math.cos(a);
  vara1= (i+1) * 1/100 * Math.PI * 2;
  varz1= Math.sin(a1);
  varx1= Math.cos(a1);
  coin_cap_geo.vertices.push(
    newTHREE.Vertex(newTHREE.Vector3(0, 0, 0)),
    newTHREE.Vertex(newTHREE.Vector3(x*r, 0, z*r)),
    newTHREE.Vertex(newTHREE.Vector3(x1*r, 0, z1*r))
  );
  coin_cap_geo.faceVertexUvs[0].push([
    newTHREE.UV(0.5, 0.5),
    newTHREE.UV(x/2+0.5, z/2+0.5),
    newTHREE.UV(x1/2+0.5, z1/2+0.5)
  ]);
  coin_cap_geo.faces.push(newTHREE.Face3(i*3, i*3+1, i*3+2));
}
coin_cap_geo.computeCentroids();
coin_cap_geo.computeFaceNormals();

varcoin_sides_texture=
  THREE.ImageUtils.loadTexture("./coin_sides.png");
varcoin_cap_texture=
  THREE.ImageUtils.loadTexture("./coin_face.png");

varcoin_sides_mat=newTHREE.MeshLambertMaterial({map:coin_sides_texture});
varcoin_sides=newTHREE.Mesh( coin_sides_geo, coin_sides_mat );

varcoin_cap_mat=newTHREE.MeshLambertMaterial({map:coin_cap_texture});
varcoin_cap_top=newTHREE.Mesh( coin_cap_geo, coin_cap_mat );
varcoin_cap_bottom=newTHREE.Mesh( coin_cap_geo, coin_cap_mat );
coin_cap_top.position.y = 0.5;
coin_cap_bottom.position.y = -0.5;
coin_cap_top.rotation.x = Math.PI;

varcoin=newTHREE.Object3D();
coin.add(coin_sides);
coin.add(coin_cap_top);
coin.add(coin_cap_bottom);

Solution 2:

In modern Three.js you can create a cylinder with an array of 3 materials:

const materials = [
  sideMaterial,
  topMaterial,
  bottomMaterial
]
const geometry = new THREE.CylinderGeometry(5, 5, 0.5, 100)
const mesh= new THREE.Mesh(geometry, materials)

Solution 3:

TypeScript function variant, that creates Object3D with 3 meshes: side, topCap and bottomCap. Works with lib version: "three": "0.102.1"

import capTop from './textures/capTopTexture.png';
 import capBottom from './textures/capBottomTexture.png';
 import capSide from './textures/sideTexture.png';

 function createCylinder(
        radiusTop: number,
        radiusBottom: number,
        height: number,
        radialSegments: number,
        heightSegments: number,
    ): Object3D {
        constcylinder=newTHREE.Object3D();

        constsidesGeo=newTHREE.CylinderGeometry(
            radiusTop,
            radiusBottom,
            height,
            radialSegments,
            heightSegments,
            true,
        );
        constsideTexture=newTHREE.TextureLoader().load(capSide, this.reRender);
        constsidesMat=newTHREE.MeshLambertMaterial({map: sideTexture});
        constsidesMesh=newTHREE.Mesh( sidesGeo, sidesMat );
        cylinder.add(sidesMesh);

        constcapTopGeo=newTHREE.CircleGeometry(radiusTop, radialSegments);
        constcapTopTexture=newTHREE.TextureLoader().load(capTop, this.reRender);
        constcapTopMat=newTHREE.MeshLambertMaterial({map: capTopTexture});
        constcapTopMesh=newTHREE.Mesh( capTopGeo, capTopMat );
        capTopMesh.position.y = height / 2;
        capTopMesh.rotation.x = - Math.PI / 2;
        cylinder.add(capTopMesh);

        constcapBottomGeo=newTHREE.CircleGeometry(radiusBottom, radialSegments);
        constcapBottomTexture=newTHREE.TextureLoader().load(capBottom, this.reRender);
        constcapBottomMat=newTHREE.MeshLambertMaterial({map: capBottomTexture});
        constcapBottomMesh=newTHREE.Mesh( capBottomGeo, capBottomMat );
        capBottomMesh.position.y = -height / 2;
        capBottomMesh.rotation.x = Math.PI / 2;
        cylinder.add(capBottomMesh);

        return cylinder;
    };


Post a Comment for "Texturing A Cylinder In Three.js"