0

I have a square shape .obj model and 2 textures. How do I apply one texture on it's top face and another on rest of faces?

Screenshot attached

Cobertos
  • 1,953
  • 24
  • 43
Nishant
  • 3
  • 4
  • take a look at https://stackoverflow.com/questions/17418118/three-js-cube-with-different-texture-on-each-face – gaitat Nov 15 '17 at 00:56
  • This isn't working. I've already tried this. – Nishant Nov 16 '17 at 05:22
  • can you post a fiddle? – gaitat Nov 16 '17 at 14:52
  • @gaitat I'll make and post a fiddle but think this is happening because I am using a custom geometry. is it possible to access faces of a custom geometry? – Nishant Nov 17 '17 at 10:43
  • you mean `geometry.faces`; this gives you the array of faces. – gaitat Nov 17 '17 at 13:40
  • @gaitat I also tried this but geometry.faces is undefined. here is the fiddle https://jsfiddle.net/nishant_mishra/n4jsz944/1/ – Nishant Nov 21 '17 at 05:31
  • I only see one texture in the fiddle. Are you trying to apply the framed box texture as the "base" object texture and then the brick/whatever texture as the second texture? – Cobertos Dec 06 '17 at 17:25
  • `geometry.faces` is undefined because you're using `OBJLoader` which uses a `THREE.BufferGeometry` internally and not a `THREE.Geometry`. See my answer. You should really post this on `GameDev.SE` though... – Cobertos Dec 06 '17 at 18:32

1 Answers1

2

There are a ton of ways to do what you're asking all with varying complexity depending on your needs. It looks like you want to apply two materials to your object and not two textures.

It looks this way because it seems you want the textures to be interchangeable so there's no way you're going to combine the images and keep resolution and OBJ & THREE.Material only support one set of uv attributes so you can't use a single material and multiple textures. So multiple materials it is...

Multiple materials

If you have two materials (2 THREE.Materials which correlate to 2 WebGL programs) then each face needs to know what material it's assigned to.

While the THREE.js multi material API has been in flux for quite a while and there are differences between THREE.Geometry and THREE.BufferGeometry, fortunately for you THREE.OBJLoader supports material groups out of the box. To get this into THREE.js, you want to apply multiple materials in your 3D editor to your object and then export the OBJ to get everything. Doing it by hand is a little harder and requires calling addGroup as shown in the docs/the link above.

In THREE.js you simply pass in all the materials as an array to your object demonstrated in this answer. I also updated your fiddle to do the same thing. Relevant code shown below

var loadingManager = new THREE.LoadingManager();
var ObjLoader = new THREE.OBJLoader(loadingManager);
var textureLoader =  new THREE.TextureLoader(loadingManager);
//Material 1 with first texture
var material = new THREE.MeshLambertMaterial({map: textureLoader.load('https://dl.dropboxusercontent.com/s/nvnacip8fhlrvm4/BoxUV.png?dl=0')});
//Material 2 with second texture
var material2 = new THREE.MeshLambertMaterial({map:
textureLoader.load('https://i.imgur.com/311w7oZ.png')});
ObjLoader.load(
    'https://dl.dropboxusercontent.com/s/hiazgei0rxeirr4/cabinet30.obj?dl=0',
    function ( object ) {
        var geo = object.children[0].geometry;
        var mats = [material, material2];
        //These are just some random groups to demonstrate multi material, you need to set these up so they actually work for your object, either in code or in your 3D editor
        geo.addGroup(0,geo.getAttribute("position").count/2,0);
        geo.addGroup(geo.getAttribute("position").count/2,
        geo.getAttribute("position").count/2,1);
        //Mesh with multiple materials for material parameter
        obj = new THREE.Mesh(geo, mats);
        obj.position.y = 3;
    });
Cobertos
  • 1,953
  • 24
  • 43