How to use glass shader to my house model? - javascript

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 ?

Related

Threejs: How to export an imported obj with Draco compressor

I only have limited javascript skills, i can get basic things working in threejs. Now I am struggeling with the draco exporter.
# Threejs.org there is an example of the Draco exporter
This example uses a generated mesh and is working perfectly:
// export mesh
var geometry = new THREE.TorusKnotBufferGeometry( 50, 15, 200, 30 );
var material = new THREE.MeshPhongMaterial( { color: 0x00ff00 } );
mesh = new THREE.Mesh( geometry, material );
mesh.castShadow = true;
mesh.position.y = 25;
scene.add( mesh );
I can import the .obj and this also works fine
new OBJLoader()
.setPath( '../models/mymodel/' )
.load( 'mymodel.obj', function ( mesh ) {
mesh.traverse( function ( child ) {
if(child.name=='mymodel_part1'){
child.material = Material1;
}
if(child.name=='mymodel_part2'){
child.material = Material2;
}
if(child.name=='mymodel_part3'){
child.material = Material3;
}
} );
scene.add( mesh );
} );
Now I want to export the mesh, and this does not work, I get a "TypeError: mesh is undefined".
So the Type is not correct, but what should it be, and how do I change it?
The problem is that OBJLoader.load() does not produce a group but an instance of THREE.Group. Hence, you have to first determine the correct mesh in the group's descendants. This however depends on the asset since OBJ files can contain multiple mesh definitions. I've prepared a live example that demonstrates this workflow. The important code section is:
var loader = new OBJLoader();
loader.load( 'https://threejs.org/examples/models/obj/tree.obj', function ( obj ) {
scene.add( obj );
mesh = obj.children[ 0 ];
} );
https://jsfiddle.net/bquxjf28/2/

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 apply texture on an object loaded by OBJLoader?

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

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