我已经从网上找到的一段代码中成功地获取了一个.obj文件,该文件可以使用three.js进行显示,这些代码可以满足我的需要。但是现在我正试图添加.mtl材质文件,并且被卡住了。
我已经尝试了一些方法,但是似乎没有任何效果。我是three.js的新手,所以在这里肯定是误会了...
这是我正在使用的当前代码,可以很好地显示我的.obj文件:
var renderer, scene, camera, Nefertiti;
var ww = window.innerWidth,
wh = window.innerHeight;
function init(){
renderer = new THREE.WebGLRenderer({canvas : document.getElementById('scene')});
renderer.setSize(ww,wh);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50,ww/wh, 0.1, 10000 );
camera.position.set(0,0,500);
scene.add(camera);
//Add a light in the scene
directionalLight = new THREE.DirectionalLight( 0xffffff, 0.8 );
directionalLight.position.set( 0, 0, 350 );
directionalLight.lookAt(new THREE.Vector3(0,0,0));
scene.add( directionalLight );
//Load the obj file
loadOBJ();
}
var loadOBJ = function(){
//Manager from ThreeJs to track a loader and its status
var manager = new THREE.LoadingManager();
//Loader for Obj from Three.js
var loader = new THREE.OBJLoader( manager );
//Launch loading of the obj file, addNefertitiInScene is the callback when it's ready
loader.load( '/mypath/Nefertiti-3d.obj', addNefertitiInScene);
};
var addNefertitiInScene = function(object){
Nefertiti = object;
//Move the Nefertiti in the scene
Nefertiti.scale.set(0.7,0.7,0.7);
Nefertiti.rotation.x = 0.5;
Nefertiti.rotation.y = 5.5;
Nefertiti.rotation.z = 0.2;
Nefertiti.position.y = -40;
Nefertiti.position.z = 1;
//Go through all children of the loaded object and search for a Mesh
object.traverse( function ( child ) {
//This allow us to check if the children is an instance of the Mesh constructor
if(child instanceof THREE.Mesh){
child.material.color = new THREE.Color(0XFFFFFF);
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
child.geometry.computeVertexNormals();
}
});
//Add the 3D object in the scene
scene.add(Nefertiti);
var canvas = renderer.domElement;
canvas.addEventListener('mousemove', onMouseMove);
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
animate();
function onMouseMove(event) {
Nefertiti.rotation.y += event.movementX * 0.001;
Nefertiti.rotation.x += event.movementY * 0.0005;
}
};
init();
这是我尝试添加的片段,以加载无效的mtl文件(为了简洁起见,我已经缩短了/ mypath /的实际路径)
var loadOBJ = function(){
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl( '/mypath/' );
mtlLoader.setPath( '/mypath/' );
var url = "/mypath/Nefertiti-3d.mtl";
mtlLoader.load( url, function( materials ) {
materials.preload();
//Manager from ThreeJs to track a loader and its status
var manager = new THREE.LoadingManager();
//Loader for Obj from Three.js
var loader = new THREE.OBJLoader( manager );
loader.setMaterials( materials );
loader.setPath( '/mypath/' );
//Launch loading of the obj file, addNefertitiInScene is the callback when it's ready
loader.load( '/mypath/Nefertiti-3d.obj', addNefertitiInScene);
object.position.y = - 95;
scene.add( object );
}, onProgress, onError );
};
通过研究,我可以看到必须有网格才能使材料起作用,但我只是无法从任何文档中弄清楚如何正确实现它。
能够在我的代码中添加MTL文件的任何帮助将不胜感激!
**编辑**
因此,根据Mugen87的建议,我将代码段更改为以下内容:
var loadOBJ = function(){
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( '/mypath/' );
var url = "/mypath/Nefertiti-3d.mtl";
mtlLoader.load( url, function( materials ) {
materials.preload();
//Manager from ThreeJs to track a loader and its status
var manager = new THREE.LoadingManager();
//Loader for Obj from Three.js
var loader = new THREE.OBJLoader( manager );
loader.setMaterials( materials );
loader.setPath( '/mypath/' );
//Launch loading of the obj file, addNefertitiInScene is the callback when it's ready
loader.load( '/mypath/Nefertiti-3d.obj', addNefertitiInScene);
}, onProgress, onError );
};
我还从three.js上的示例中包含了MTLLoader.js(我不确定这是否正确,我发现很难找到有关此的信息),并且在控制台中遇到以下错误:
Uncaught SyntaxError: Cannot use import statement outside a module
(index):136 Uncaught TypeError: THREE.MTLLoader is not a constructor
at loadOBJ ((index):136)
at init ((index):132)
at (index):199
loadOBJ @ (index):136
init @ (index):132
(anonymous) @ (index):199
有任何想法吗?我在代码中的MTL方式有问题吗?
最佳答案
object.position.y = - 95;
scene.add( object );
我想您已经从official OBJ/MTL example的两行代码中复制了,对吗?不幸的是,它们在这里没有意义,因为
object
是undefined
。请记住,addNefertitiInScene
是您的onLoad()
回调,它负责将加载的对象添加到场景中。此外,
mtlLoader.setBaseUrl( '/mypath/' );
不必要。该方法已删除了很长时间。还应使用浏览器的开发工具来确保已实际加载MTL文件。
three.js R109