ThreeJs入门31-WebGL模型篇:加载obj模型的一些问题

「这是我参与2022首次更文挑战的第35天,活动详情查看:2022首次更文挑战

示例代码采用three.js-r73版本: cdnjs.cloudflare.com/ajax/libs/t…

上一节我们主要做了将obj模型加载到场景中,并且给模型添加了纹理贴图,这节我们来具体讲述下OBJLoader使用过程中需要注意的一些问题。让我们来看看吧。

使用blender查看obj模型

  • 我们可以使用一些3D模型制作软件来查看obj模型,比如blender
  • 选择文件->导入->导入.obj文件,选择我们的obj模型文件进行导入

image.png

  • 导入效果

image.png

  • 这也说明了我们的模型本身是没有纹理贴图的(没有穿衣服),如果想让它变得好看就需要添加纹理贴图
  • 没有贴图的模型,我们也称为白模

使用OBJLoader加载模型

  • 我们的OBJLoader源码的load部分和VTKLoader是差不多的,我们这里使用了自定义的loader管理器,以及监听加载进度

自定义loader管理器

  • 稍后传给OBJLoader
var manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
    console.log(item, loaded, total);
}
复制代码

加载模型资源,监听模型加载进度

var objLoader = new THREE.OBJLoader(manager)
objLoader.setCrossOrigin("Anonymous");  // 解决跨域问题
objLoader.load(`${base_url}/models/obj/male02/male02.obj`, function (object) {
    ....
    // 处理模型数据
}, onProgress, onError)

// 加载模型进度
var onProgress = function (xhr) {
    if (xhr.lengthComputable) {
        var percentComplete = xhr.loaded / xhr.total * 100;
        console.log(Math.round(percentComplete, 2) + '% downloaded');
    }
}
var onError = function (xhr) {

}
复制代码
  • lengthComputable我们通过获取xhr可以看到这个属性,当这个属性为true时,说明模型数据长度可以计算
  • 通过计算加载的数据/总数据可以计算当前加载的百分比

处理模型数据

  • 模型加载完成以后,我们可以拿到一个object对象,这个对象就是模型对象。它是一个Object3D
objLoader.load(`${base_url}/models/obj/male02/male02.obj`, function (object) {
    console.log(object);
    // 遍历子模型
    object.traverse(function (child) {
        if (child instanceof THREE.Mesh) {
            child.material.map = texture
        }
    })

    object.position.y = -80
    scene.add(object)
}, onProgress, onError)
复制代码
  • object.traverse()方法继承自Object3D,主要用来遍历子模型
traverse: function ( callback ) {
	// 回调函数传递自身
  callback( this );
	
  var children = this.children;
	
  for ( var i = 0, l = children.length; i < l; i ++ ) {
		// 遍历子模型递归调用
    children[ i ].traverse( callback );

  }

},
复制代码
  • 这个方法首先通过回调,把自身(object)传递过去
  • 然后递归遍历子object
  • 达到遍历所有子模型的目的
  • 如果子模型属于网格模型,那么就给他的material.map添加纹理贴图,这样我们的模型就有纹理贴图了(有衣服穿了)

为什么要遍历子模型

  • 通过blender查看,我们的一个模型是由很多个部分组成的

image.png

  • 现在我选中的部分是模型的身体,也就是左侧黄色钩边部分,如果我们删掉,会看到还有其他部分。

image.png

  • 所以我们要遍历所有的子模型,给每个模型都添加纹理贴图

codepen示例代码

猜你喜欢

转载自juejin.im/post/7066967346409111589