Mesh is invisible when texture material is used

I am trying to add numbers to the sides of a decahedron but for some reason the mesh created is invisible there is some issue in the materials. But I am not sure what the issue is. What am i doing wrong ? -

const verticesGeo = [
        [0, 0, 1],
        [0, 0, -1],
      ].flat();

      for (let i = 0; i < sides; ++i) {
        const b = (i * Math.PI * 2) / sides;
        verticesGeo.push(-Math.cos(b), -Math.sin(b), 0.105 * (i % 2 ? 1 : -1));
      }

      const facesGeo = [
        [0, 2, 3],
        [0, 3, 4],
        [0, 4, 5],
        [0, 5, 6],
        [0, 6, 7],
        [0, 7, 8],
        [0, 8, 9],
        [0, 9, 10],
        [0, 10, 11],
        [0, 11, 2],
        [1, 3, 2],
        [1, 4, 3],
        [1, 5, 4],
        [1, 6, 5],
        [1, 7, 6],
        [1, 8, 7],
        [1, 9, 8],
        [1, 10, 9],
        [1, 11, 10],
        [1, 2, 11],
      ].flat();
      const args = [verticesGeo, facesGeo, radius, 0];
      let decaGeometry = new THREE.PolyhedronGeometry(...args);
let g = decaGeometry;
        let materialOptions = {
          specular: 0x172022,
          color: 0xf0f0f0,
          shininess: 40,
          flatShading: true,
          //shading: THREE.FlatShading,
      };

        let materials = [];
        for (let text = 0; text < 10; ++text) {
            let canvas = document.createElement("canvas");
            let context = canvas.getContext("2d");
            let ts = Math.max(128, Math.pow(2, Math.floor(Math.log(1.5) / Math.log(2)))) * 2;
            canvas.width = canvas.height = ts;
            context.font = ts / (1 + 2 * 1) + "pt Arial";
            context.fillStyle = tempFillColor;
            context.fillRect(0, 0, canvas.width, canvas.height);
            context.textAlign = "center";
            context.textBaseline = "middle";
            context.fillStyle = tempTextColor;
            context.fillText(text, canvas.width / 2, canvas.height / 2);
            let texture = new THREE.Texture(canvas);
            texture.needsUpdate = true;

            materials.push(new THREE.MeshPhongMaterial(Object.assign({}, materialOptions, { map: texture })));
        }
        console.log(materials)
        

        decahedron = new THREE.Mesh(g, materials);
        scene.add(decahedron)

Is this option with numbers on sides not acceptable? How to put numbers to the sides of a cube and later get which number landed on top - #17 by prisoner849

1 Like

@prisoner849 , those are fine, but I am unable to replicate it on a 10 side dice.

@prisoner849, sorry to interfere; @Samarth_Bagga, if you use multiple materials, you need to add groups in the geometry – each group will use selected (by you) material from the array.

When I add group to your code, I get the dice shown:

image

PS. I don’t know (or care) which material to which face should go, so ignore the fact that the textures are mangled in the snapshot.

1 Like

I’m glad you joined the thread :slight_smile:

@Samarth_Bagga
Ten materials per die O_o
Maybe, makes sense to use re-computed UVs and a texture atlas?

1 Like

@prisoner849 , I tried that method through this code -

let g = decaGeometry;

let tileDimension = new THREE.Vector2(4, 5);
let tileSize = 512;

let c = document.createElement("canvas");
c.width = tileSize * tileDimension.x;
c.height = tileSize * tileDimension.y;
let ctx = c.getContext("2d");
ctx.fillStyle = tempFillColor;
ctx.fillRect(0, 0, c.width, c.height);

let uvs = [];

let baseUVs = [
    new THREE.Vector2(0.67, 1), // br
    new THREE.Vector2(0, 0.5),  // bt
    new THREE.Vector2(1, 0.5),  // tl
    new THREE.Vector2(0.67, 0)  // bl
];

for (let i = 0; i < 10; i++) {
    let u = i % tileDimension.x;
    let v = Math.floor(i / tileDimension.x);
    uvs.push(
        (baseUVs[0].x + u) / tileDimension.x,
        (baseUVs[0].y + v) / tileDimension.y,
        (baseUVs[1].x + u) / tileDimension.x,
        (baseUVs[1].y + v) / tileDimension.y,
        (baseUVs[2].x + u) / tileDimension.x,
        (baseUVs[2].y + v) / tileDimension.y,
        (baseUVs[3].x + u) / tileDimension.x,
        (baseUVs[3].y + v) / tileDimension.y
    );

    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.font = `bold 175px Arial`;
    ctx.fillStyle = tempTextColor;
    let text = i + 1;
    if (i === 5) {
        text += ".";
    }
    ctx.fillText(
        text,
        (u + 0.5) * tileSize,
        c.height - (v + 0.5) * tileSize
    );
}

g.setAttribute("uv", new THREE.Float32BufferAttribute(uvs, 2));

let tex = new THREE.CanvasTexture(c);
tex.colorSpace = THREE.SRGBColorSpace;

let m = new THREE.MeshPhongMaterial({
    map: tex,
});
decahedron = new THREE.Mesh(g, m);

But the numbers are not mapping correctly on the sides.