2

I added texture to my triangle geometry. But all was one plain colour base on the lightest value. Then I learn that I should assign UVs. But same problem but with darkest colour of my texture (see picture).

Here the code:

var material = new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader().load(texture), overdraw: true } );
var geometry = new THREE.Geometry();
// 1re marche de 3 (30 degrées)
geometry.vertices.push(new THREE.Vector3(0.0, 0.0, 0.0));
geometry.vertices.push(new THREE.Vector3(longueurTotalFacteur, largeur, 0.0));
geometry.vertices.push(new THREE.Vector3(0.0, largeur, 0.0));
geometry.vertices.push(new THREE.Vector3(0.0, 0.0, -epaisseur));
geometry.vertices.push(new THREE.Vector3(longueurTotalFacteur, largeur, -epaisseur));
geometry.vertices.push(new THREE.Vector3(0.0, largeur, -epaisseur));
geometry.faces.push(new THREE.Face3(0, 1, 2)); // Dessus
geometry.faces.push(new THREE.Face3(5, 4, 3)); // Dessous
geometry.faces.push(new THREE.Face3(3, 1, 0)); // Côté long
geometry.faces.push(new THREE.Face3(4, 1, 3)); // Côté long
geometry.faces.push(new THREE.Face3(4, 2, 1)); // Côté court
geometry.faces.push(new THREE.Face3(5, 2, 4)); // Côté court
geometry.faces.push(new THREE.Face3(5, 0, 2)); // Côté moyen
geometry.faces.push(new THREE.Face3(3, 0, 5)); // Côté moyen

assignUVs(geometry);
... (snipped)...
function assignUVs(geometry) {
    geometry.faceVertexUvs[0] = [];
    geometry.faces.forEach(function(face) {
        var components = ['x', 'y', 'z'].sort(function(a, b) {
            return Math.abs(face.normal[a]) > Math.abs(face.normal[b]);
        });

        var v1 = geometry.vertices[face.a];
        var v2 = geometry.vertices[face.b];
        var v3 = geometry.vertices[face.c];

        geometry.faceVertexUvs[0].push([
            new THREE.Vector2(v1[components[0]], v1[components[1]]),
            new THREE.Vector2(v2[components[0]], v2[components[1]]),
            new THREE.Vector2(v3[components[0]], v3[components[1]])
        ]);
    });
    geometry.uvsNeedUpdate = true;
}

Here what I get:

enter image description here

Wilt
  • 41,477
  • 12
  • 152
  • 203
Martin Pineault
  • 87
  • 1
  • 14

1 Answers1

1

You cannot do like this:

var material = new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader().load(texture), overdraw: true } );

Texture loading is an asynchronous process. You need to apply the texture in the onLoad callback. Please refer to the documents for THREE.TextureLoader here.

For your example:

var material = new THREE.MeshBasicMaterial( { overdraw: true } );
var url = //your texture path...
var onLoad = function(texture){
    material.map = texture;
    material.needsUpdate = true;
}
var loader = new THREE.TextureLoader();
loader.load(url, onLoad);

UPDATE

When you calculate your UV's you need to do something with offset and range. Check the computeUVs from this example fiddle; you might need to change it a bit for your stairs geometry...

function computeUVs(geometry) {

  geometry.computeBoundingBox();

  var max = geometry.boundingBox.max,
      min = geometry.boundingBox.min;
  var offset = new THREE.Vector2(0 - min.x, 0 - min.y);
  var range = new THREE.Vector2(max.x - min.x, max.y - min.y);
  var faces = geometry.faces;
  var vertices = geometry.vertices;

  geometry.faceVertexUvs[0] = [];

  for (var i = 0, il = faces.length; i < il; i++) {

    var v1 = vertices[faces[i].a],
        v2 = vertices[faces[i].b],
        v3 = vertices[faces[i].c];

    geometry.faceVertexUvs[0].push([
      new THREE.Vector2((v1.x + offset.x) / range.x, (v1.y + offset.y) / range.y),
      new THREE.Vector2((v2.x + offset.x) / range.x, (v2.y + offset.y) / range.y),
      new THREE.Vector2((v3.x + offset.x) / range.x, (v3.y + offset.y) / range.y)
    ]);
  }
  geometry.uvsNeedUpdate = true;
}

This code is based on this stackoverflow answer.

Community
  • 1
  • 1
Wilt
  • 41,477
  • 12
  • 152
  • 203
  • I updated my code with your answer, but nothing has changed. var material1 = new THREE.MeshBasicMaterial(); var geometry = new THREE.Geometry(); // Geometry setting vector here removed assignUVs(geometry); var onLoad = function(_texture) { material1.map = _texture; material1.needsUpdate = true; }; geometry.userData = modele; // Keep it for later use. mesh[no] = new THREE.Mesh( geometry, material1 ); groupe.add( mesh[no] ); var loader = new THREE.TextureLoader; loader.load(texture, onLoad); – Martin Pineault Jul 14 '16 at 12:48
  • @Wilt The `TextureLoader.load` function returns a texture object. The async part is within the the `TextureLoader.load` function in a `THREE.ImageLoader` which updates the texture. The code you posted and said does not work, does in fact work. – 2pha Jul 14 '16 at 12:59
  • Though, I'm not sure of the implications of doing it that way – 2pha Jul 14 '16 at 13:14
  • @MartinPineault I updated my answer... I was only quoting what does not work. You should carefully [read the docs](http://threejs.org/docs/#Reference/Loaders/TextureLoader) and check some examples. Loading a texture is not complicated as long as you follow the docs... – Wilt Jul 14 '16 at 14:36
  • @2pha I posted that *'You cannot do like this'* :D I formatted as a quote now ;) and added an example... – Wilt Jul 14 '16 at 14:38
  • I think it has something to do with the scale. Like if I have to scale down the image. That way I only see one colour, it's the so-scaled part with one colour in it that I see. I don't pass any argument for the same texture but with BoxGeometry and it's all fine. How do I find out the value and pass it to the loader? – Martin Pineault Jul 14 '16 at 18:35
  • @MartinPineault Maybe check my other answer [to a similar question here](http://stackoverflow.com/a/37830305/1697459), it was also an UV issue. If it doesn't help please leave a comment... – Wilt Jul 15 '16 at 08:46
  • @Wilt Did you look at the image I provided on first in this post? Texture is there but showing wrong! – Martin Pineault Jul 16 '16 at 01:32
  • @MartinPineault I updated my answer, hope it will be more useful for you after this update... – Wilt Jul 16 '16 at 08:16
  • @Wilt PEFECT! That did it. Thank you. – Martin Pineault Jul 16 '16 at 11:55