cover

模型格式

首先我们需要了解模型文件的常用格式,Three.js 引擎支持的格式非常的多,我们最为常见的格式有 .obj + .mtl ,但使用这种模型格式存在一个问题,.obj 是静态模型,不支持动画数据存储,无法使用模型的动画,官方建议使用 glTF 这种模型格式 , 但是glTF目前应用比较少,有条件的朋友可以使用Blender导出glTF2文件,这次我们先了解如何使用相对常用的.obj + .mtl的形式

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<template>
<div>
<div id="container"></div>
</div>
</template>

<script>
import * as Three from 'three' //导入three.js
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js' //导入OBJLoader 读取obj模型
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js' //导入MTLLoader 读取mtl材质
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' //使用OrbitControls控制模型的旋转,放大,缩小
export default {
name: 'Demo',
data () {
return {
camera: null,
scene: null,
renderer: null,
light: null,
controls: null
}
},
methods: {
// 外部模型加载函数
loadObj () {
let that = this
// 材质读取,包含材质
new MTLLoader().load('/obj/demo.mtl', materials => {
materials.preload()
// 模型读取
new OBJLoader().setMaterials(materials).load('/obj/demo.obj', obj => {
obj.scale.set(5, 5, 5)
obj.position.set(0, 0, 0)
//在场景中加入坐标系
let axes = new Three.AxesHelper(100)
that.scene.add(obj)
that.scene.add(axes)
}, function (xhr) {
// onProgress回调
console.log((xhr.loaded / xhr.total * 100) + '% loaded')
}, function (err) {
// onError回调
console.log(err)
})
})
},
init: function () {
this.scene = new Three.Scene()
this.scene.add(new Three.AmbientLight(0x999999))// 环境光
this.light = new Three.DirectionalLight(0xdfebff, 0.45)// 从正上方(不是位置)照射过来的平行光,0.45的强度
this.light.position.set(50, 200, 100)
this.light.position.multiplyScalar(0.3)
this.scene.add(this.light)
// 初始化相机
this.camera = new Three.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000)
this.camera.position.set(10, 90, 65)
this.camera.lookAt(this.scene.position)
// 初始化控制器
this.controls = new OrbitControls(this.camera)
this.controls.target.set(0, 0, 0)
this.controls.minDistance = 80
this.controls.maxDistance = 400
this.controls.maxPolarAngle = Math.PI / 3
this.controls.update()
// 渲染模型 alpha为透明背景
this.renderer = new Three.WebGLRenderer({
alpha: true
})
// this.renderer.setClearColor(0x000000)
this.renderer.setPixelRatio(window.devicePixelRatio)// 为了兼容高清屏幕
this.renderer.setSize(window.innerWidth, window.innerHeight)

const container = document.getElementById('container')
container.appendChild(this.renderer.domElement)

// this.renderer = new Three.WebGLRenderer({
// antialias: true,
// alpha: true // 默认情况下为黑色场景,此处设置为透明(即白色场景)
// })
},
animate: function () {
requestAnimationFrame(this.animate)
this.renderer.render(this.scene, this.camera)
}
},
mounted () {
this.init()
this.loadObj()
this.animate()
}
}
</script>
<style scoped>
#container {
width: 100vw;
height: 100vh;
overflow: hidden;
}
</style>