Reputation: 89
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:
Upvotes: 2
Views: 1976
Reputation: 44316
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);
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.
Upvotes: 1