当然,如果你时间充裕,又对模型创作感兴趣,那你确实可以花时间好好学习3D建模软件的使用,这样以后就可以自己创建所需模型,由自己导出与导入模型文件。因为从建模软件导出模型的过程中,其实有特别多的坑,一个不小心,导出的模型可能就大相径庭。所以依赖于别人导出的模型文件,有时你都不知道到底问题出在哪里。
threejs中导入外部文件所需的辅助函数都在https://github.com/mrdoob/three.js/tree/dev/examples/js/loaders下可以找到。这里除了JSON模型文件的导入外,其余模型文件都需要引用其对应名称的辅助函数。例如:导入OBJ格式的模型,除了导入必要的three.js文件外,还需要在界面中引用OBJLoader.js文件。而JSONLoader函数集成在three.js中,所以无需再导入其他辅助文件!
理解就是,如:导出的json文件既可以存物体的模型,也可以存其材质及动画信息。
4.1 JSON格式文件导入——使用JSONLoader函数
// 实例化一个JSONLoader类
var loader = new THREE.JSONLoader();
// 导入资源
loader.load(
// 导入的模型文件所在 URL
'models/animated/monster/monster.js',
// 资源加载成功后执行的函数
//@params geometry 传入的模型,只能是单个模型,不能是一个场景
// @params materials 传入的材质,是个数组
function ( geometry, materials ) {
var material = materials[ 0 ];
var object = new THREE.Mesh( geometry, material );
scene.add( object );
}
);
4.2 OBJ格式文件导入——使用OBJLoader函数
敲黑板!!!!!前面已经讲过,obj格式文件都是和mtl格式文件搭配使用,因为obj格式的文件只能存模型,不能存模型材质和动画,而材质都存于mtl文件中。
4.2.1 当只导入模型,不导入材质,模型的材质由导入后用代码定义
//图片加载loader
var texture = new THREE.Texture();
var loader = new THREE.ImageLoader( );
//导入资源
loader.load(
//材质图片所在url
'textures/UV_Grid_Sm.jpg',
function ( image ) {
texture.image = image;
texture.needsUpdate = true;
} );
//obj文件加载loader
var loader = new THREE.OBJLoader( );
//导入资源
loader.load(
//obj模型所在url
'obj/male02/male02.obj',
// 资源加载成功后执行的函数
//@params object 传入的模型,只能是单个模型,也可能是一个group,视构建的model而定
function ( object ) {
//taverse函数为遍历object的每个子mesh,传入的child为每个mesh
//该示例中的object为一个group,有多个mesh组成
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material.map = texture;
}
} );
object.position.y = - 95;
scene.add( object );
});
4.2.2 当既导入模型,又导入材质时
//当mtl中引用了dds类型的图片时,还需导入DDSLoader文件。
//这里的src路径视实际开发而定
THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
var mtlLoader = new THREE.MTLLoader();
//设置路径,也可不是设置,在load中加载完整路径也可
mtlLoader.setPath( 'obj/male02/' );
mtlLoader.load( 'male02_dds.mtl',
// 资源加载成功后执行的函数
//@params materials THREE.MTLLoader.MaterialCreator
function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( 'obj/male02/' );
objLoader.load( 'male02.obj', function ( object ) {
object.position.y = - 95;
scene.add( object );
});
});
4.3 其他模型文件导入类似,具体可参考官网examples
https://threejs.org/examples/ 中的 loader/* 部分
threejs R86版本中,有convert-to-threejs.py这样一个python文件,该文件的作用是将模型文件(.fbx,.dae, .obj, .3ds)转换成json格式。详细地转换操作可参考以下链接文章:
convert_to_threejs.py 使用配置
注意事项:
对以上链接文章做个小补充,这里箭头所引入的python版本最好一致,反正我当时不一致好像最后转化出bug了。
2. 如何用Threejs导入基于JSON格式的场景文件?
所谓场景文件,也就是文件中列出了各个物体和变换层级,以及所有的材质,纹理,相机和光源信息。讲道理,如果成功导入一个场景文件后,进行基本渲染就可以查看整个3D场景了。之前threejs的版本中进行场景渲染调用THREE.SceneLoader即可,不过现在threejs R86版本已用THREE.ObjectLoader替代。
给个简单示例:
//@params url 场景文件所在路径
new THREE.ObjectLoader().load( url, function ( loadedScene ) {
scene = loadedScene;
// If the loaded file contains a perspective camera, use it with adjusted aspect ratio...
scene.traverse( function ( sceneChild ) {
if ( sceneChild.type === 'PerspectiveCamera' ) {
camera = sceneChild;
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
camera.updateProjectionMatrix();
}
} );