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 );
} );
Related
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' );
}
);
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
}
I have been working on ThreeJS for a while, i tried to load a house model using OBJ + MTL loader, now i need to apply glass shaders for window materials
i managed to load the model successfully by
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl( 'new/' );
mtlLoader.setPath( 'new/' );
mtlLoader.load( 'House.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( 'new/' );
objLoader.load( 'House.obj', function ( object ) {
object.position.y = - 5;
object.scale.x=object.scale.y=object.scale.z=0.05
object.castShadow = true;
object.receiveShadow = true;
object.traverse( function( node ) { if ( node instanceof THREE.Mesh ) { node.castShadow = true;
node.receiveShadow = true; } } );
mesh = object;
scene.add( mesh );
});
});
Now i would like to add glass shaders for house windows in this model, in which way should i code, how can i take the reference from loaded house to make a shader ?
Any other way to code glass shader ?
I'm currently working on my little project using three.js, but I am having hard time mapping texture on objects loaded by THREE.OBJLoader. There is no such problem for three.js built in geometry. I'm really confused now...
// Load the model from obj file [teapot, 74KB]
var onProgress = function ( xhr ) {
};
var onError = function ( xhr ) {
};
//var oCubeMap = THREE.ImageUtils.loadTexture(imageNames);
var objTexture = new THREE.ImageUtils.loadTexture(textureImage);
var oMaterial = new THREE.MeshLambertMaterial( { map: objTexture } );
var ooMaterial = new THREE.MeshPhongMaterial( { color: 0x99CCFF } );
var thisTexture = THREE.ImageUtils.loadTexture( textureImage, {}, function() {
renderer.render(scene, camera);
} );
var loader = new THREE.OBJLoader();
loader.load(teapot, function (object) {
object.position.set(8, -5, -25);
object.scale.set(0.04, 0.04, 0.04);
object.rotation.set(0, 180 * Math.PI / 180, 0);
// object.color = '0x99CCFF';
object.material = ooMaterial;
// object.texture = thisTexture;
scene.add(object);
}, onProgress, onError);
As you can see I've tried several things like color, material and texture but nothing worked so far. Can anyone tell me how to apply a texture onto this object?
OBJLoader returns an object with children. Add the following to your loader callback function:
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material.map = texture;
}
} );
Make sure your model geometry has UVs, otherwise textures are not supported.
three.js r.73
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