ThreeJs入门30-WebGl模型篇:Obj模型的加载

1,761 阅读2分钟

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

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

yuque_diagram.jpg

之前给大家介绍过VTK模型格式,VTK模型如何解析,以及如何加载到场景中。其实我们使用VTK模型基本足够满足我们的使用的。但是我们有各种各样格式的模型,为了满足需求,我们需要使用对应的loader来加载模型。 ​

Obj模型介绍

  • 使用三维软件导出.obj模型文件的时候,会同时导出一个材质文件.mtl, .obj和.stl文件包含的数据一样都是几何体对象的顶点位置、顶点法向量等顶点相关数据, 材质文件.mtl包含的是RGB颜色值等材质信息。
  • 加载.obj三维模型的时候,可以只加载.obj文件,然后借助three.js引擎自定义材质对象Material,也可以同时加载obj和mtl文件。
  • obj文件不包含场景的相机、光照信息,不能导出骨骼动画、变形动画,如果希望导出光照信息、相机信息、骨骼动画信息、变形动画信息,可以选择fbx、gltf等格式。
  • objLoader官方文档: threejs.org/docs/index.…

实战

初始化场景

function initScene() {
    scene = new THREE.Scene();
}

初始化摄像机

我们设置摄像机45度角,近距离为1,远距离为2000,把摄像机放在[0,0,100]的位置

const near = 1;
const far = 2000;

function initCamera() {
    camera = new THREE.PerspectiveCamera(45, width / height, near, far);
    camera.position.z = 100;
    scene.add(camera);
}

初始化灯光

  • 我们添加环境光和平行光
function initLight() {
    scene.add(new THREE.AmbientLight(0x101030));

    light = new THREE.DirectionalLight(0xffeedd);
    light.position.set(0, 0, 1);
    scene.add(light);

}

加载Obj模型

创建一个loading管理器

var manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
    console.log(item, loaded, total);
}

加载材质

// 加载材质
var texture = new THREE.Texture();

var loader = new THREE.ImageLoader(manager);
loader.load('../../static/textures/UV_Grid_Sm.jpg', function (image) {
    texture.image = image;
    texture.needsUpdate = true;
})
  • 首先我们初始化一个材质THREE.Texture
  • 通过THREE.ImageLoader加载图片作为材质

加载模型

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

}

var loader = new THREE.OBJLoader(manager)
loader.load('../../static/models/obj/male02/male02.obj', function (object) {
    object.traverse(function (child) {
        if (child instanceof THREE.Mesh) {
            child.material.map = texture
        }
    })

    object.position.y = -80
    scene.add(object)
}, onProgress, onError)
  • 首先我们初始化THREE.OBJLoader
  • 通过objLoader加载.obj文件,获取到对应数据,将我们的材质赋值给obj模型
  • 最后添加到场景中

展示效果

image.png

  • 我们这里使用了一个带有纹理坐标的图片作为了材质,后面我们会讲纹理坐标相关的知识。

codepen示例代码