Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three.js - Adding texture to custom geometry

I'm working on applying a simple material with a texture map to a custom mesh. I couldn't find any examples that I could understand, so I made this fiddle to demonstrate what I'm trying to achieve.

/// MATERIAL
var texture = new THREE.TextureLoader().load( "https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/crate.gif" );
var material = new THREE.MeshBasicMaterial( { 
    map: texture,
  side: THREE.DoubleSide
} );

// TRIANGLE
var geometry2 = new THREE.Geometry();
var v1 = new THREE.Vector3(0,200,0);
var v2 = new THREE.Vector3(0,0,-100);
var v3 = new THREE.Vector3(0,0,100);
geometry2.vertices.push(v1);
geometry2.vertices.push(v2);
geometry2.vertices.push(v3);
geometry2.faces.push( new THREE.Face3( 0, 1, 2 ) );
meshCustom = new THREE.Mesh(geometry2, material);
scene.add(meshCustom);

// CUBE
var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

https://jsfiddle.net/benaloney/L7js807k/8/

I just want the triangle to have the same texture as the cube, I understand there needs to be UV coordinates on the mesh for this to work, but am unsure of how to implement this.

enter image description here

like image 606
Ben Winding Avatar asked Nov 15 '16 01:11

Ben Winding


2 Answers

The texture on the triangle looks weird though... Just in case, adapting the UVs to your actual object might help :

Your updated fiddle

Here's how :

//texture
    var texture2 = new THREE.TextureLoader().load( "https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/crate.gif" );


//material
    var material2 = new THREE.MeshBasicMaterial( { 
        map: texture2,
      side: THREE.DoubleSide
    } );

  // TRIANGLE
    var geometry2 = new THREE.Geometry();
    var v1 = new THREE.Vector3(0,200,0);
    var v2 = new THREE.Vector3(0,0,-100);
    var v3 = new THREE.Vector3(0,0,100);
    geometry2.vertices.push(v1);
    geometry2.vertices.push(v2);
    geometry2.vertices.push(v3);
    geometry2.faces.push( new THREE.Face3( 0, 1, 2 ) );

//manually setting your UVs
    geometry2.faceVertexUvs[0].push([
            new THREE.Vector2(0,0),        //play with these values
            new THREE.Vector2(0.5,0),
            new THREE.Vector2(0.5,0.5)
        ]);

//updating the uvs
    geometry2.uvsNeedUpdate = true;
like image 116
Console-buche Avatar answered Oct 08 '22 08:10

Console-buche


Got it working, so I did need UV coordinates on the Geometry. Thanks to this other question:

https://stackoverflow.com/a/27317936/2419584

I added this function and passed the geometry through it.

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;
}

This automatically generates the UV coords, from the geometry, this then allows textures with images to show up on custom geometries.

Here is my updated working jsfiddle.

https://jsfiddle.net/benaloney/L7js807k/9/

like image 2
Ben Winding Avatar answered Oct 08 '22 08:10

Ben Winding