Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning materials to an OBJLoader model in three.js

Tags:

I've imported an OBJ model with the following code:

var loader = new THREE.OBJLoader(); loader.addEventListener('load', function (geometry) {     object = geometry.content;     scene.add(object); }); loader.load('ship.obj'); 

It works fine, but whenever I try to add a material to it, it either has no effect or the model disappears. I assumed I could do it like this:

var ship = new THREE.Mesh(object, material); 

But that doesn't work. does anyone know of a way to do this, or if it's even possible? I've tried using OBJMTLLoader too, but it just adds complication while still not allowing me to change the material.

like image 642
Hobo Joe Avatar asked Apr 24 '13 19:04

Hobo Joe


People also ask

What is material in three js?

Materials manage the texture and color of objects in Three. js. A material covers an object, the colors, or textures on a surface. To use an analogy, materials are like the clothes we wear.


2 Answers

EDIT: This answer is now outdated. Instead, see the answer by @mightypile.


Assuming you have properly defined material, try this:

loader.addEventListener( 'load', function ( event ) {      var object = event.content;      object.traverse( function ( child ) {          if ( child instanceof THREE.Mesh ) {              child.material = material;          }      } );      scene.add( object );  }); 
like image 130
WestLangley Avatar answered Oct 03 '22 23:10

WestLangley


Using @WestLangley's answer, I kept getting the error

loader.addEventListener is not a function 

and my page would not load. According to Atul_Mourya at discourse.threejs.org, it is a better (or more up-to-date?) idea to implement the function inside of a callback while loading. I combined his advice with the documentation and @WestLangley's helpful function answering this same question to come up with:

var ship_material = new THREE.MeshBasicMaterial( { color: 0x444444 } ); var loader = new THREE.OBJLoader(); loader.load( 'ship.obj',     function( obj ){         obj.traverse( function( child ) {             if ( child instanceof THREE.Mesh ) {                 child.material = ship_material;             }         } );         scene.add( obj );     },     function( xhr ){         console.log( (xhr.loaded / xhr.total * 100) + "% loaded")     },     function( err ){         console.error( "Error loading 'ship.obj'")     } ); 

This example also implements callbacks for progress and error, and it worked for me.

like image 21
mightypile Avatar answered Oct 03 '22 22:10

mightypile