It seems that OBJMTLLoader has been removed recently (r74?), but I cannot track down any documentation on how to use the two replacement classes. Here is the current code I have (adapted from Three.js Cookbook):
<script src="../libs/three.r74.js"></script>
<script src="../libs/MTLLoader.js"></script>
<script src="../libs/OBJMTLLoader.js"></script>
<script>
var legoManMesh = null;
function init(){ /* Create my scene here */ }
var loader = new THREE.OBJMTLLoader();
loader.load("../assets/models/lego.obj", "../assets/models/lego.mtl",
function (obj) {
legoManMesh = obj;
init();
}
);
</script>
(BTW, when moving from r69 to r74 the above code fails with "TypeError: loader.setCrossOrigin is not a function")
ADDITIONAL:
The sample lego.mtl file here references a texture png using a relative path.
# Blender MTL File: 'LEGO Minifigure - Blendswap.blend'
# Material Count: 2
newmtl Cap
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.990000 0.120000 0.120000
Ks 0.500000 0.500000 0.500000
Ni 1.000000
d 1.00000
illum 2
newmtl Minifig
Ns 874.999998
Ka 0.000000 0.000000 0.000000
Kd 0.800000 0.800000 0.800000
Ks 0.200000 0.200000 0.200000
Ni 1.000000
d 1.000000
illum 2
map_Kd ../textures/Mini-tex.png
Here is code that demonstrates how to load .obj and .mtl files in r74:
var mesh = null;
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( "https://threejs.org/examples/models/obj/walt/" );
mtlLoader.load( 'WaltHead.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( "https://threejs.org/examples/models/obj/walt/" );
objLoader.load( 'WaltHead.obj', function ( object ) {
mesh = object;
mesh.position.y = -50;
scene.add( mesh );
} );
} );
Fiddle at: http://jsfiddle.net/g2evz0q5/
Updated answer to reflect correction for completeness.
Related
I would like to render my user generated obj instead of loading from file.
In my example below, objString represents a cube.
The browser just show a dark screen. I'm expecting the display of a green cube rotating.
I wonder what I'm missing
import React from 'react';
import * as THREE from "three";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader"
class App extends React.Component {
componentDidMount() {
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
let loader = new OBJLoader();
// obj string below represents a cube
var objString = `
v 0.000000 2.000000 2.000000
v 0.000000 0.000000 2.000000
v 2.000000 0.000000 2.000000
v 2.000000 2.000000 2.000000
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
f 1 2 3 4
f 8 7 6 5
f 4 3 7 8
f 5 1 4 8
f 5 6 2 1
f 2 6 7 3
`;
var cube = loader.parse(objString);
scene.add( cube );
// var geometry = new THREE.BoxGeometry( 1, 1, 1 );
// var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
// var cube = new THREE.Mesh( geometry, material );
// scene.add( cube );
camera.position.z = 5;
var animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
}
render() {
return (
<div></div>
);
}
}
export default App;
OBJLoader actually works fine. The problem is that the loader returns meshes with MeshPhongMaterial which is a lit material. Since you don't have any lights in your scene, you just have a black screen. Try it like so:
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 5;
let loader = new THREE.OBJLoader();
// obj string below represents a cube
var objString = `
v 0.000000 2.000000 2.000000
v 0.000000 0.000000 2.000000
v 2.000000 0.000000 2.000000
v 2.000000 2.000000 2.000000
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
f 1 2 3 4
f 8 7 6 5
f 4 3 7 8
f 5 1 4 8
f 5 6 2 1
f 2 6 7 3
`;
var cube = loader.parse(objString);
scene.add( cube );
var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
hemiLight.position.set( 0, 20, 0 );
scene.add( hemiLight );
var dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( - 3, 10, - 10 );
scene.add( dirLight );
var animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
body {
margin: 0px;
}
canvas {
display: block;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.116.1/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.116.1/examples/js/loaders/OBJLoader.js"></script>
(Note: I've posted this on the Clara.io Forums and while it's only been a day, I've not received any replies. I figured I'd try StackOverflow and update my Clara.io post.)
I'm hoping (guessing) that this is a quick-fix and that I'm missing something basic, but I've searched for quite a bit of time looking for a solution. I'm seeing my final render has the color grey in place of the assigned material, whereas all other non-extruded faces render fine.
I'm learning the Clara.io interface, (along with the basic essentials of 3D modeling really), and have a basic cube with a few extruded faces. In the screenshot below you can see the normals of all faces, including the extruded ones. This is a result of Dr. Google saying "look at your normals, they're probably flipped". It doesn't appear so.
While I put this in the "Rendering" category, I could've also applied it to "ThreeJS" as I'm wondering if it's something I've configured wrong in the ThreeJS scene. I'm using a MeshStandardMaterial along with a normal and roughness map:
var materialTest5 = new THREE.MeshStandardMaterial( {
normalMap: textureLoaderQ.load( "/textures/metal18/metal_plates_18_nm.jpg" ),
roughnessMap: textureLoaderQ.load( "/textures/metal18/metal_plates_18_rough.jpg" ),
map: textureLoaderQ.load( "/textures/metal18/metal_plates_18_dif.jpg" )
} );
var loader5 = new THREE.OBJLoader();
loader5.load( "/models/capsule/test-01.obj", function ( group ) {
for ( var index = 0; index < group.children.length; index++ ) {
var geometry = group.children[ index ].geometry;
var meshTest5 = new THREE.Mesh( geometry, materialTest5 );
scene.add( meshTest5 );
}
} );
They appear like this:
You can see the grey faces. Try as I might, I can't get those faces to render using the same maps as the other faces. I've tried flipping normals, I've tried altering the material in ClaraIO, and a few other settings that were futile.
Within the Clara.io, I can see a similar situation:
Anyone see this before? Have an idea?
Thank you.
Jon
[UPDATE] Here are the OBJ and MTL files I'm using:
OBJ
MTL
MTL
# Blender MTL File: 'None'
# Material Count: 1
newmtl Standard
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 1.000000 1.000000 1.000000
Ks 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd metal_plates_18_dif.jpg
OBJ (Not too many points, so I figured I could add it here too).
# Blender v2.74 (sub 0) OBJ File: ''
# www.blender.org
mtllib test-01.mtl
o Box
v 0.500000 0.500000 0.500000
v 0.500000 0.500000 0.000000
v 0.500000 0.500000 -0.500000
v 0.500000 0.000000 0.500000
v 0.500000 0.000000 0.000000
v 0.500000 0.000000 -0.500000
v 0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.000000
v 0.500000 -0.500000 -0.500000
v -0.500000 0.500000 -0.500000
v -0.500000 0.500000 0.000000
v -0.615470 0.615470 0.615470
v -0.500000 0.000000 -0.500000
v -0.500000 0.000000 0.000000
v -0.500000 0.000000 0.500000
v -0.500000 -0.500000 -0.500000
v -0.500000 -0.500000 0.000000
v -0.500000 -0.500000 0.500000
v 0.000000 0.500000 -0.500000
v 0.000000 0.500000 0.000000
v 0.000000 0.506330 0.500000
v 0.000000 -0.500000 0.500000
v 0.000000 -0.500000 0.000000
v 0.000000 -0.500000 -0.500000
v 0.000000 0.000000 0.500000
v 0.000000 0.000000 -0.500000
v -0.615470 0.115470 0.115470
v -0.615470 0.615470 0.115470
v -0.615470 0.115470 0.615470
v -0.115470 0.615470 0.615470
v -0.115470 0.615470 0.115470
v -0.115470 0.115470 0.615470
vt 0.000000 1.000000
vt 0.000000 0.500000
vt 0.500000 0.500000
vt 0.500000 1.000000
vt 1.000000 0.500000
vt 1.000000 1.000000
vt 0.000000 0.000000
vt 0.500000 0.000000
vt 1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 -1.000000
vn -0.707100 0.000000 -0.707100
vn -0.707100 -0.707100 0.000000
vn 0.707100 0.707100 -0.000000
vn 0.000000 0.707100 -0.707100
vn 0.000000 -0.707100 0.707100
vn 0.707100 0.000000 0.707100
usemtl Standard
s 1
f 1/1/1 4/2/1 5/3/1 2/4/1
f 2/4/1 5/3/1 6/5/1 3/6/1
f 4/2/1 7/7/1 8/8/1 5/3/1
f 5/3/1 8/8/1 9/9/1 6/5/1
f 10/1/2 13/2/2 14/3/2 11/4/2
f 28/4/2 27/3/2 29/5/2 12/6/2
f 13/2/2 16/7/2 17/8/2 14/3/2
f 14/3/2 17/8/2 18/9/2 15/5/2
f 10/1/3 11/2/3 20/3/3 19/4/3
f 19/4/3 20/3/3 2/5/3 3/6/3
f 28/2/3 12/7/3 30/8/3 31/3/3
f 20/3/3 21/8/3 1/9/3 2/5/3
f 18/1/4 17/2/4 23/3/4 22/4/4
f 22/4/4 23/3/4 8/5/4 7/6/4
f 17/2/4 16/7/4 24/8/4 23/3/4
f 23/3/4 24/8/4 9/9/4 8/5/4
f 12/1/5 29/2/5 32/3/5 30/4/5
f 21/4/5 25/3/5 4/5/5 1/6/5
f 15/2/5 18/7/5 22/8/5 25/3/5
f 25/3/5 22/8/5 7/9/5 4/5/5
f 3/1/6 6/2/6 26/3/6 19/4/6
f 19/4/6 26/3/6 13/5/6 10/6/6
f 6/2/6 9/7/6 24/8/6 26/3/6
f 26/3/6 24/8/6 16/9/6 13/5/6
f 11/7/7 14/7/7 27/7/7 28/7/7
f 14/7/8 15/7/8 29/7/8 27/7/8
f 21/7/9 20/7/9 31/7/9 30/7/9
f 20/7/10 11/7/10 28/7/10 31/7/10
f 15/7/11 25/7/11 32/7/11 29/7/11
f 25/7/12 21/7/12 30/7/12 32/7/12
[UPDATE 2] Problem solved thanks to a comment #manthrax made below.
I rebuilt the UV map using the Clara.io "UV Map" option in the Object Tools section. I also had to set the "Projection" to "Box" so the newly created extruded faces didn't have a skewed/angled diffuse layout. While initially I had only included a "diffuse" image, I added both a "normal" and "specular" map this time around. The image below is a bit bright, and loses the metallicity of my original render above, but that's because I put the specular to white (#ffffff). I'll play around with those settings next. Here's the final result:
I also wanted to note that I had to change the Three JS code a bit, to handle the MTL file that Clara.io generated:
var meshZ = null;
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( "/models/capsule/" );
mtlLoader.load( 'test-01.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( "/models/capsule/" );
objLoader.load( 'test-01.obj', function ( object ) {
meshZ = object;
scene.add( meshZ );
} );
} );
Thanks again, #manthrax.
Onto the next 3D OBJ creation learning curve...
In you loader.load callback.. instead of looping through children, can you try:
group.traverse((e)=>{if(e.material)e.material = materialTest5;})
instead of looping through children?
Also, could you post your .OBJ file so we can take a look?
Here I have a simple script that uses Three.JS MTL Loader and OBJ loader to load a model and the material for the model.
Now when it loads the model it only loads the first objects color and the rest it leaves white. Can anyone shed some light on what may be the cause of thise ?
Here is my code
var loader = new THREE.MTLLoader();
loader.load('http://ustarp.com/3DModels/WebsiteParts/Polished Aluminum/Underbody/11228.mtl', function (materials) {
materials.preload();
var objLoaderOfficeChair = new THREE.OBJLoader();
objLoaderOfficeChair.setMaterials(materials);
objLoaderOfficeChair.load('http://ustarp.com/3DModels/WebsiteParts/Polished Aluminum/Underbody/11228.obj', function (object) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ){
x=document.getElementsByClassName("popup"); // Find the elements
for(var i = 0; i < x.length; i++){
x[i].innerHTML += "<li class='mi_child'>"+child.name+"</li>"; // Change the content
}
}
});
object.name = 'Part1';
object.scale.set(50,50,50);obj3d.add( object );
object.updateMatrix();
model2 = object;
scene.add(object);
});
});
Here is an example of the model being shown.
http://ustarp.com/3DModels/?part=2c75cf2681788adaca63aa95ae028b22
Your mtl file is not formatted correctly:
# WaveFront *.mtl file (generated by Autodesk ATF)
newmtl 254,254,255
Ka 0.996078 0.996078 1.000000
Kd 0.996078 0.996078 1.000000
Ks 0.996078 0.996078 1.000000
Ns 1000.000000
d 1.000000
newmtl 229,31,31
Ka 0.898039 0.121569 0.121569
Kd 0.898039 0.121569 0.121569
Ks 1.000000 1.000000 1.000000
Ns 1000.000000
d 1.000000
newmtl takes a string to be used as an identifier.
Edit
What you can do is replace the string 254,254,255 with the string white and the string 229,31,31 with the string redish in the mtl file and the obj file.
I need a basic material in my mesh.
I have this material in my MTL file:
newmtl window
Ns 0.000000
Ka 0.000000 0.000000 0.000000
Kd 0.888930 0.994660 0.000000
Ks 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 1
what attribute makes material to be "THREE Basic Material"?
The given MTL file translates to
new THREE.MeshLambertMaterial( { color: new THREE.Color( 0.888930, 0.994660, 0 ) } );
I've successfully loaded a 3d model that I triangulated using Blender. Trouble is its all black and I can't figure out how to get it to show color or textures.
I have an ambient light initialized like this:
function init() {
scene = new THREE.Scene;
camera = new THREE.PerspectiveCamera(
75, (window.innerWidth) / (window.innerHeight),
1, 10000);
camera.position.x = 500;
camera.position.z = 100;
camera.lookAt(new THREE.Vector3(0, 0, 0));
camera.rotateZ(90 * Math.PI / 180);
scene.add(new THREE.AmbientLight(0xffffff));
populate();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
document.body.appendChild(renderer.domElement);
document.addEventListener('keydown', function(event) { keydown(event);
});
}
Here's the .mtl that goes with the .obj
Blender MTL File: 'mq9.blend'
Material Count: 4
newmtl Material__69
Ns 9.803922
Ka 0.000000 0.000000 0.000000
Kd 0.225882 0.225882 0.225882
Ks 0.900000 0.900000 0.900000
Ni 1.000000
d 1.000000
illum 2
newmtl _6___Default
Ns 19.607843
Ka 0.000000 0.000000 0.000000
Kd 0.800000 0.800000 0.800000
Ks 0.900000 0.900000 0.900000
Ni 1.000000
d 1.000000
illum 2
map_Kd missile.jpg
newmtl mq_9
Ns 31.372549
Ka 0.000000 0.000000 0.000000
Kd 0.800000 0.800000 0.800000
Ks 0.990000 0.990000 0.990000
Ni 1.000000
d 1.000000
illum 2
map_Kd predator.jpg
map_Bump predator_Normal.jpg
newmtl mq_90
Ns 31.372549
Ka 0.000000 0.000000 0.000000
Kd 0.800000 0.800000 0.800000
Ks 0.990000 0.990000 0.990000
Ni 1.000000
d 1.000000
illum 2
map_Kd predator.jpg
map_Bump predator_Normal.jpg
The various .jpgs are all found but for some reason they don't seem to be rendering by three.js. I'm wondering if the jpgs need to be modified somehow to reflect the triangulation?
Screenshot: