I have ".obj" and ".mtl" files of a model and I'm loading it via OBJMTLLoader
. ".mtl" specifies texture to apply to a model, and three.js loads model and renders it with applied texture just fine.
But here's the thing.
Once an object is loaded, I would like to apply another texture onto it. This is because first texture represents surface material of an object. And second texture is a drawing, that I'd like to position at a specific location on a model.
My question is: how to apply a second texture onto already loaded (and texturized) object?
I see that three.js creates an instance of THREE.Object3D
, and that instance has "children" array with one instance of THREE.Mesh
.
When I try to apply a texture to that mesh (mesh.material.map = texture
), I lose initial texture.
I looked into this question about applying multiple textures and JSONLoader but didn't find an answer.
I also tried using new THREE.MeshFaceMaterial( materials )
(as suggested in this answer) but unsuccessfully.
UPDATE:
I tried @WestLangley's suggestion to use multi-material object, but am still unable to render one material on top of another one.
I made this simple demo, adapted from three.js OBJLoader — http://dl.dropboxusercontent.com/u/822184/webgl_multiple_texture/index.html
I'm using THREE.SceneUtils.createMultiMaterialObject
as suggested, passing it cloned geometry of main mesh loaded from .obj. I'm also giving it 2 textures — one for entire surface, another one — for front surface of the model.
But this doesn't work. I added 2 checkboxes that toggle "visible" property of corresponding materials. You can see that materials are present, but I can't see the first one from beneath second one.
The crux of the loading/rendering is as follows:
var texture = THREE.ImageUtils.loadTexture('fabric.jpg');
var texture2 = THREE.ImageUtils.loadTexture('table.jpg');
texture2.offset.set(-0.65, -2.5);
texture2.repeat.set(4, 4);
var loader = new THREE.OBJLoader();
loader.addEventListener( 'load', function ( event ) {
var mainMesh = event.content.children[0].children[0];
multiMaterialObject = THREE.SceneUtils.createMultiMaterialObject(
mainMesh.geometry.clone(), [
new THREE.MeshLambertMaterial({ map: texture2 }),
new THREE.MeshLambertMaterial({ map: texture })
]);
multiMaterialObject.position.y = -80;
scene.add(multiMaterialObject);
});
loader.load( 'male02.obj' );
UPDATE #2
At this point, I think the best bet is to use THREE.ShaderMaterial
to apply one texture onto another. I see some examples of using one texture but still unsure how to display both in overlaid state. I'm also not sure how to position texture at a specific location on a mesh.
See Question&Answers more detail:
os