Use multiple Textures in export loader `obj` file in three.js - javascript

I tried to use different textures in export loader obj file.
I am able to make my object visible on the scene but I couldn't set either its size nor its shape.
Any idea on what is wrong/is missing in my code ?
var loader = new THREE.OBJLoader();
loader.load(
'models/Sofa/sofa.obj',
function (object) {
var geometry = object.children[ 0 ].geometry;
var materials = [];
materials.push(new THREE.MeshBasicMaterial( { map : THREE.ImageUtils.loadTexture( 'models/Sofa/Texturses/1.jpg')}));
materials.push(new THREE.MeshBasicMaterial( { map : THREE.ImageUtils.loadTexture( 'models/Sofa/Texturses/paradis_beige.jpg')}));
materials.push(new THREE.MeshBasicMaterial( { map : THREE.ImageUtils.loadTexture( 'models/Sofa/Texturses/2.jpg')}));
mesh = THREE.SceneUtils.createMultiMaterialObject(geometry, materials);
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = material;
}
});
scene1.add(mesh);
},
function ( xhr ) {
returnValue = ( xhr.loaded / xhr.total * 100 ) + '% loaded';
console.log(returnValue);
},
function ( error ) {
console.log( 'An error happened' );
}
);

Related

Texture on object doesn't show up

What I want
I am quite new to Three.js and I am trying to apply a texture to a loaded object.
The problem
I have tried quite a few things and still not sure how to do this. I don't get any errors and the object loads in but with no texture.
My code
var loader6 = new THREE.OBJLoader();
// load a resource
loader6.load(
// resource URL
'models/Chair.obj',
// called when resource is loaded
function ( object ) {
object.scale.x = 20;
object.scale.y = 30;
object.scale.z = 20;
object.rotation.y = -0.3;
object.position.z = -500;
object.position.x = 30;
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
console.log(texture);
child.material.map = texture;
}
});
var texture = new THREE.TextureLoader().load('models/Chair.mtl');
object6 = object;
scene.add( object6 );
},
Any help?
You can not load .mtl file using TextureLoader, you have to use MTLLoader for that. MTLLoader should load the texture. Then you have to set the material to OBJLoader using 'setMaterial' function.
Checkout this code -
new THREE.MTLLoader()
.setPath( 'path to the material folder' )
.load( 'material_file.mtl', function ( materials ) {
materials.preload();
new THREE.OBJLoader()
.setMaterials( materials )
.setPath( 'path to the obj folder' )
.load( 'objModel.obj', function ( object ) {
object.position.y = - 95;
scene.add( object );
}, onProgress, onError );
} );

How to applying THREE.EdgesGeometry in a object loaded with THREE.OBJLoader?

I try several times to implement the edges in a model loader with the OBJLoader but can't do it.
Mloader = new THREE.MTLLoader();
Mloader.setPath( dir );
Mloader.load( mtl_dir, function ( materials ) {
materials.preload();
OLoader = new THREE.OBJLoader();
OLoader.setMaterials( materials );
OLoader.setPath( dir );
OLoader.load( name_file, function ( object ) {
object.scale.set( scale, scale, scale );
scene.add( object );
var edges = new THREE.EdgesGeometry( object, 11 );
var line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( {color: 0x111111 } ) );
line.scale.set( scale, scale, scale );
scene.add( line )
} );
} );
The model load fine, but the edges don't.
When the model is loader with the STLloader the edges of the geometry render fine, but i need to do it with .obs files.
var loader = new THREE.STLLoader();
loader.load(dir, function (geometry) {
material = new THREE.MeshPhongMaterial({
color: 0xAAAAAA,
specular: 0x111111,
shininess: 200
});
var edges = new THREE.EdgesGeometry(geometry, 11);
var line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({color: 0x111111}));
line.scale.set(scale, scale, scale);
scene.add(line)
});
STL vs OBJ Loader
Thanks, yes it a group. The code with the solution:
Mloader = new THREE.MTLLoader();
Mloader.setPath( dir );
Mloader.load( mtl_dir, function ( materials ) {
materials.preload();
OLoader = new THREE.OBJLoader();
OLoader.setMaterials( materials );
OLoader.setPath( dir );
OLoader.load( name_file, function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.castShadow = true;
edges = new THREE.EdgesGeometry( child.geometry,11);
line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( {
color: 0x111111
} ) );
line.scale.set( scale, scale, scale );
line.position.set( 0, 0.7, 0 );
scene.add( line );
}
} );
object.scale.set( scale, scale, scale );
object.position.set( 0, 0.7, 0 );
scene.add( object );
} );
} );

how to use multiple texture objLoader, mtlLoader in three.js?

I can able to visible object but don't work multiple material textures images. It's visible black color. what is missing in my code?
case 'plant':
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath('models/LivingRoom/Sample1/');
mtlLoader.load( '3dbts103601T.mtl', function( materials ) {
materials.preload();
var loader = new THREE.OBJLoader();
loader.setPath('models/LivingRoom/Sample1/');
loader.load('3dbts103601T.obj', function (object) {
var geometry = object.children[ 0 ].geometry;
var materials = [];
var mat1=new THREE.MeshBasicMaterial( { map : THREE.ImageUtils.loadTexture('models/LivingRoom/Sample1/3dbts103601T1.jpg')});
var mat2=new THREE.MeshBasicMaterial({ map : THREE.ImageUtils.loadTexture('models/LivingRoom/Sample1/3dbts103601T2.jpg')});
materials.push(mat1);
materials.push(mat2);
Mesh = THREE.SceneUtils.createMultiMaterialObject(geometry,materials);
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.materials = materials;
}
});
scene1.add(object);
});
});
break;

Texture issue while using THREE.TextureLoader over deprecated THREE.ImageUtils.loadTexture

I was using this function to add Texture on a Cylinder.
function createElementMaterial() {
THREE.ImageUtils.crossOrigin = '';
var t = THREE.ImageUtils.loadTexture( IMG_MACHINE );
t.wrapS = THREE.RepeatWrapping;
t.wrapT = THREE.RepeatWrapping;
t.offset.x = 90/(2*Math.PI);
var m = new THREE.MeshBasicMaterial();
m.map = t;
return m;
}
which is working and adds Texture, but in console it sets a warning message.
THREE.ImageUtils.loadTexture has been deprecated. Use
THREE.TextureLoader() instead.
Then following this documentation from threejs.org. I changed the function to this.
function createElementMaterial() {
var loader = new THREE.TextureLoader();
// load a resource
loader.load(
// resource URL
IMG_MACHINE,
// Function when resource is loaded
function ( texture ) {
// do something with the texture
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.offset.x = 90/(2*Math.PI);
var material = new THREE.MeshBasicMaterial( {
map: texture
} );
},
// Function called when download progresses
function ( xhr ) {
console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
},
// Function called when download errors
function ( xhr ) {
console.log( 'An error happened' );
}
);
}
With this code I am not being able to get that texture wrapping cylinder. Here's the before and after image.
TIA.
You have to return a material from your function. You can do it like this:
function createElementMaterial() {
var material = new THREE.MeshBasicMaterial(); // create a material
var loader = new THREE.TextureLoader().load(
// resource URL
IMG_MACHINE,
// Function when resource is loaded
function ( texture ) {
// do something with the texture
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.offset.x = 90/(2*Math.PI);
material.map = texture; // set the material's map when when the texture is loaded
},
// Function called when download progresses
function ( xhr ) {
console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
},
// Function called when download errors
function ( xhr ) {
console.log( 'An error happened' );
}
);
return material; // return the material
}

threejs wireframe with the object materials

i want to get the wireframe of an object that is loaded from OBJMTLLoder ,so here i have the code as like below
var loader = new THREE.OBJMTLLoader();
loader.load( 'obj/male02/male02.obj', 'obj/male02/male02_dds.mtl', function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh )
{
child.geometry.computeFaceNormals();
var geometry = child.geometry;
console.log(geometry);
geometry.dynamic = true;
material = new THREE.MeshLambertMaterial();
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
var useWireFrame = true;
if (useWireFrame) {
mesh.traverse(function (child) {
if (child instanceof THREE.Mesh) child.material.wireframe = true;
});
}
}
object.position.y = - 80;
scene.add( object );
});
} );
this is working well, and i can see the wireframe on my object, unfortunately here my object material is changed into MeshLambertMaterial. but i want to get the wireframe of the object with the default material of the object loaded, i can use variety of Material as in the threejs document, but none of them give me a result with the default object material
i got fixed it by add child.material for material , so here is the answer
loader.load( 'obj/male02/male02.obj', 'obj/male02/male02_dds.mtl', function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh )
{
//child.geometry.computeFaceNormals();
var geometry = child.geometry;
//console.log(geometry);
//geometry.dynamic = true;
material = child.material;
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
var useWireFrame = true;
if (useWireFrame) {
mesh.traverse(function (child) {
if (child instanceof THREE.Mesh)
{
child.material.wireframe = true;
child.material.color = new THREE.Color( 0x6893DE );
}
});
}
}
object.position.y = - 80;
//scene.add( object );
});
here i added material = child.material; as like geometry = child.geometry; and it worked fine

Categories

Resources