VR 效果 前端使用 three.js 加载 Obj(三维模型文件)

4/10/2021 工具

# VR 效果 前端使用 three.js 加载 Obj(三维模型文件)

前言:我对 three.js 并不熟!只是朋友有这个需求,写了几个 demo 运行,能看~。如果想深入学习,还需要多看看官方文档,这里只做个记录,学习难度:仅供入门学习

下面的 demo 其实都是网上大神的代码,我只是收集,拼凑显示了出来 ~代码我已经全部放在码云了。想要源文件的可以到码云下载 ~ demoVR-three-demo (opens new window) 。文件夹里面准备了有 3 个模型,都可以自己改着路径玩玩~

在线预览地址

obj 文件类型 (opens new window)

drc 文件类型 (opens new window)

# three.js 显示 obj 文件

  • 引入需要的 JS 资源。都是 three 的文件
<script src="js/three.min.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/OBJLoader.js"></script>
<script src="js/MTLLoader.js"></script>
<script src="js/jQuery-2.1.4.min.js"></script>
1
2
3
4
5
  • 然后下面这段 JS。就是初始化一些插件(three)

  • MTLLoader 这个是用来渲染 3D 模型的材质的,就像 demo1 中的车模型,如果不用材质的话,整台车都是白色的

  • OBJLoader 这个就是主角了。用于渲染.obj 文件的

  • Scene,PerspectiveCamera,AmbientLight,WebGLRenderer 这些把,原谅我也只是个入门新手,不懂,哈哈哈哈 😃 不过大概的意思就是说创建光源,创建视角的角度,感兴趣的可以看下文档~

  • loadModel 这个方法就是开始渲染的了,前面的代码都相当于在搭建环境,在这个方法里面先加载了模型的皮肤(材质太难听了,就称之为皮肤把)。然后在加载 obj 文件,把皮肤附在 obj(原型上) 注意这里是 2 个文件 一个是 humvee.obj原型文件,另一个是 humvee.mtl(皮肤)

  • 这段代码是没有 html 标签的,因为用的 canvas 渲染,canvas 都是用 document.body.....动态插入的可以看下代码库中的 demo-1-objfile文件就懂了

<script>
  var mtlLoader = new THREE.MTLLoader()
  var objLoader = new THREE.OBJLoader()

  var scene = new THREE.Scene()
  var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 10000)
  camera.position.set(0, 500, 500)

  var renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.setClearColor(0x177fb3, 1)
  document.body.appendChild(renderer.domElement)

  var lightAm = new THREE.AmbientLight('#DFDFDF', 1)
  scene.add(lightAm)

  var lightDirect = new THREE.DirectionalLight(0xffffff, 0.6)
  lightDirect.position.set(50, 200, -50)
  scene.add(lightDirect)

  var controls = new THREE.OrbitControls(camera, renderer.domElement)

  loadModel('obj/humvee/', 'humvee', { x: 0, y: 0, z: 0 })
  render()

  function render() {
    requestAnimationFrame(render)
    renderer.render(scene, camera)
  }
  function loadModel(folder, name, position) {
    mtlLoader.setBaseUrl(folder)
    mtlLoader.setPath(folder)
    mtlLoader.load(name + '.mtl', function(materials) {
      objLoader.setMaterials(materials)
      objLoader.load(folder + name + '.obj', function(object) {
        object.position.set(position.x, position.y, position.z)
        object.rotateX(-Math.PI / 2)
        scene.add(object)
      })
    })
  }
</script>
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

# drc 文件的渲染

前面讲到了 obj 文件。可以看到我第一个 demo 的文件还算比较小(5MB 左右)。可是稍微大点的模型加载就非常久了!

于是我们用到了谷歌爸爸的的开源插件 draco 来进行压缩,压缩完成后便是 drc文件了! 对于 draco 下面会讲到

先说渲染:

有个明显的缺陷:无法加载皮肤!(mtl)文件 反正我是折腾了很久,没找到

和 obj 文件不一样的是,他的加载需要用到

<script src="js/three.min.js"></script>
<!-- 不同的地方 -->
<script src="js/DRACOLoader.js"></script>
<script src="js/draco_decoder.js"></script>
<script src="js/OrbitControls.js"></script>
<!-- MTL我试过,没成功~成功的小伙伴可以分享给我 -->
<script src="js/MTLLoader.js"></script>
1
2
3
4
5
6
7

代码就不贴了。到码云下载把~


# 下载了码云的代码,打开 index.html 是空白啊!

由于 obj 文件的特殊性,反正各种原因,需要自己跑服务来查看。nginx 了解下? 对于前端来说,可能 nginx 有点陌生,不过 nginx 也算是开发的基础技能了。

nginx 劝退?不要急,那我们以前端的方式来打开!

  • 安装 http-server
  • 运行文件

node 命令应该懂了把,他是一个 node 库,用于实现基础的站点。打开本地的端口的

npm install -g http-server

# 在项目目录中,比如在 demoVR-three-demo/demo-1-objfile中运行这句命令
http-serve -p 8080 ./

# http-server 就是说运行一个本地服务
# -p 8080 指定 8080端口
# ./ 指定运行目录,因为运行后,他会自动找到 index.html 如果没找到那就是404了。如果没有 index.html 那么可以在服务跑起来后 127.0.0.1:8080/你的文件名这样也行
1
2
3
4
5
6
7
8

注意看我的示例链接:http://jioho.gitee.io/vr-three-demovr-three-demo/demo-2-drcfile/ 我是在 demoVR-three-demo 文件夹跑得服务,所以后面还得指定是 demo-2-drcfile

言传有点难懂,自己运行一次比听 100 次强

# 重头戏!draco 的使用

  • window 下,需要 vsstudio 来构建项目,我就没那环境了。不过我找到了一个已经构建好的~,不想折腾的可以直接下载

【window 环境】已经编译的 draco (opens new window)

把 obj 文件可拷贝进来,然后运行:

./draco_encoder -i testdata/360.obj -o testdata/360.obj.drc
1
  • -i 执行压缩命令
  • -o 指定输出的目录和文件名(默认可以不填,不填就是原文件名.obj.drc)

我的 2 个文件,一个 1.4G,压缩到了 500mb | 另外一个 5MB。压缩到了 130KB(就是车子的模型,可以看下 demo-1 和 demo-2 的区别。在码云上都有)


github - draco (opens new window) 谷歌爸爸出品,必属精品啊

draco 的依赖: draco 需要 cmark 编译 cmark 需要 OpenSSL 我忘记了哪里,还需要 gcc+ 毕竟编译器都要用嘛

# 基础的gcc+先装
apt-get install gcc+
1
2

如果是要下载的话,直接下载 https://github.com/google/draco/archive/1.3.6.tar.gz (opens new window) 这个链接的把

#个人建议 先建一个 draco 目录(我是在 /usr/local/software/  software是自创目录了)
mkdir draco

cd draco

# 注意是在linux环境下载,下载到你们自己放软件的目录去
wget https://github.com/google/draco/archive/1.3.6.tar.gz

# 解压。解压后就可以看到 draco-1.3.6 文件夹了
tar zxvf 1.3.6.tar.gz

# 在创建一个编译后的文件夹,和 draco-1.3.6 同级
mkdir draco-build
1
2
3
4
5
6
7
8
9
10
11
12
13

我的文件目录一开始不懂事,改了名字,影响不大哈,你们正常应该是 draco-1.3.6draco-build

开始编译源码(这个需要 CMark 环境才能编译) 安装 CMark 因为我的是 ubuntu。所以可以直接用 apt 下载

sudo apt -y install cmake
1

可以看到的是,下载失败,😦 因为这个包需要科学上网!。那我们就手动编译 cmark

打开 CMark 官网 (opens new window)

复制链接,回到我的 software 目录

# 等待下载完成
wget https://github.com/Kitware/CMake/releases/download/v3.17.1/cmake-3.17.1.tar.gz

tar zxvf  cmake-3.17.1.tar.gz

# 解压完成,看到 cmake-3.17.1(根据你们版本号来)
cd cmake-3.17.1

# 执行 ./bootstrap
./bootstrap
1
2
3
4
5
6
7
8
9
10

上面有说到。cmake 依赖OpenSSL。如果没装的话,会看到。 一定要注意报错信息,看下有没有出现 error 之内的字眼,然后看下缺什么库,毕竟每个人的环境都不一样,可能我有的库你们也没装~ 我的很明显可以看到 Could Not find OpenSSl 找不到 OpenSSl

# 安装 OpenSSl
apt-get install OpenSSl

# 重新执行 bootstrap
./bootstrap

# 如果一切正常后,执行。因为 make的时候要创建文件的,不想该权限了,直接给sudo执行
sudo make

# 完成后在执行一个 make install
sudo make install
1
2
3
4
5
6
7
8
9
10
11

通常 make 报错是因为权限不足,无法创建目录,这个自己稍微留意下

折腾那么久。cmark 可算是装上,开始编译 draco

回到 software 目录。进入到 draco 的 draco-build 目录(这是一开始自己手动创建的目录了)

# 我这里执行 draco 是因为我文件夹改过名字
# 没改名字的还是执行 draco-1.3.6
# 而且这是在 build 目录, build和 draco同级才行!
sudo cmake ../draco

# 执行make命令
make
1
2
3
4
5
6
7

如果一切顺利,draco-build 目录下是这样的,红色圈住的就是我们要的文件了!

draco_encoder 可以将.obj 压缩成.drc draco_decoder 是可以把 drc 转回 obj 的

我创建了一个 testdata 文件夹 然后把我们的 obj 文件放了进去,运行

./draco_encoder -i testdata/360.obj -o testdata/360.obj.drc
1
  • -i 执行压缩命令
  • -o 指定输出的目录和文件名(默认可以不填,不填就是原文件名.obj.drc)

可以看到压缩比例非常的高!! 1.4G 压缩成了 500MB

你们看 demo-1 和 demo-2 的模型文件也可以看到,车的模型原大小是 5M。压缩后才 130 多 KB


three 和 draco 折腾到此结束了,看到自己的作品,虽然都是很简单的 demo,可是还是特别有成就感,毕竟这种平时见的不多(是我见得不多,哈哈哈哈)。最起码也是可以运行小 demo,作为一个基础入门学习了~

对于我自己来说,学习一个新技术,让我直接看文档我会崩溃的,我还是比较喜欢做出来一点小东西后在去研究文档

如果想要更加完整,炫酷的效果,的确要多看文档才知道

如果文章有用,可以到下载区下载相关资源,赞助我一些 C 币,最后附上全部的下载链接 VR-three-demo csdn 资源 (opens new window)

【window 环境】已经编译的 draco (opens new window)

Last Updated: 11/29/2022, 8:35:30 PM