threejs如何导入3d模型以及常见问题整理
Threejs库提供了多种模型的载入解析库,支持如下格式模型载入gltf,obj,fbx,stl等多种格式模型
这里主要讲解一下obj模型的导入,及将obj文件转成文件更小的json格式导入。
Threejs支持了许多格式的3D模型导入,包括*.obj、 *.sea、*.3mf 、*.amf、*.sea、*.pmd、*.json等。
这里主要讲解一下obj模型的导入,及将obj文件转成文件更小的json格式导入。
目前一般采用obj格式,这个是格式非常通用,在Windows上都可以直接预览
美术提供的一般为3Dmax项目文件夹,里面包含了.max文件以及贴图图片等资源,用3DMAX打开.max文件可以看到3D模型,3Dmax格式通过菜单可以直接转换成obj格式
这个问题,obj本身不带贴图,需要mtl同时导入,另外导出obj+mtl时,如果贴图路径没设置正确,可以用文本编辑器打开mtl文件,把图片路径修改为项目的相对路径。
单独导入obj是没有贴图的。如果只有obj可以用threejs的textureload导入贴图,并在导入obj后, 把obj的mesh.materital设置为导入的贴图。
使用mtlLoader和objLoaer加载obj模型及贴图
加载带mtl材质的obj模型,需要先定义mtl对象并加载mtl之外再加载obj模型。此时需要引用threejs两个js库
<script src=”../js/lib/threejs/MTLLoader.js”></script>
<script src=”../js/lib/threejs/OBJLoader.js”></script>
THREE.MTLLoader()函数说明:
- setBaseUrl():设置材质路径
- setPath():设置mtl文件所在路径
- load(filename,onSuccess(materials ),onProgress(xhr),onError(error)):mtl文件名、 加载成功后回调处理(参数为生成的材质库)、加载过程中回调处理(xhr对象属性可计算出已完成加载百分比)、失败回调处理
THREE.OBJLoader() 函数说明:
- setMaterials( materials ):设置obj使用的材质贴图
- setPath( options.objPath ):设置obj文件所在路径
- load( filename,onSuccess(object ),onProgress(xhr),onError(error)):obj文件名、 加载成功后回调处理(参数为生成的三维对象)、加载过程中回调处理(xhr对象属性可计算出已完成加载百分比)、失败回调处理。
在onSuccess(object ){}回调里我们可以对生成的三维对象做一些处理:对材质进行调色、设置透明度、设置贴图模式等,对设置旋转、缩放、位置摆放、自发光颜色、环境光颜色。
如果obj文件代表的三维对象是由多个子模型构成的模型组合,我们可以调用object.traverse(function(child){})来对每个子模型进行处理。
以下简单封装成一个函数
function createMtlObj(options){
THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl( options.mtlBaseUrl );//设置材质路径
mtlLoader.setPath( options.mtlPath );//设置mtl文件路径
mtlLoader.load( options.mtlFileName, function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );//设置三维对象材质库
objLoader.setPath( options.objPath );//设置obj文件所在目录
objLoader.load( options.objFileName, function ( object ) {
if(typeof options.completeCallback==”function”){
options.completeCallback(object);
}
}, function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
if(typeof options.progress ==”function”){
options.progress( Math.round(percentComplete, 2));
}
//console.log( Math.round(percentComplete, 2) + ‘% downloaded’ );
}
}, function(error){
});
});
}
调用示例:
createMtlObj({
mtlBaseUrl:”../resource/haven/”,
mtlPath: “../resource/haven/”,
mtlFileName:”threejs.mtl”,
objPath:”../resource/haven/”,
objFileName:”threejs.obj”,
completeCallback:function(object){
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;//设置贴图模式为双面贴图
child.material.emissive.r=0;//设置rgb通道R通道颜色
child.material.emissive.g=0.01;//设置rgb通道G通道颜色
child.material.emissive.b=0.05;//设置rgb通道B通道颜色
child.material.transparent=true;//材质允许透明
//child.material.opacity=0;//材质默认透明度
//child.material.shading=THREE.SmoothShading;//平滑渲染
}
});
object.emissive=0x00ffff;//自发光颜色
object.ambient=0x00ffff;//环境光颜色
// object.rotation.x= 0;//x轴方向旋转角度
object.position.y = 0;//位置坐标X
object.position.z = 0;//位置坐标y
object.scale.x=1;//缩放级别
object.scale.y=1;//缩放级别
object.scale.z=1;//缩放级别
object.name=”haven”;//刚体名称
object.rotation.y=-Math.PI;//初始Y轴方向旋转角度
scene.add(object);//添加到场景中
},
progress:function(persent){
$(“#havenloading .progress”).css(“width”,persent+”%”);
}
})
常见问题:
1.此时如果在之前没有添加光源,在浏览器上看到的可能是一片黑色,通过增加光源可以将物体显现出来。比例添加一个全局光
var ambient = new THREE.AmbientLight( 0xffffff );
scene.add( ambient );
2.另外由于自动导出的法线贴图名称中带有中文,需要将mtl中map_bump和对应的法向贴图名称改成非中文命名。
WEBGL学习网 » threejs如何导入3d模型以及常见问题整理