【ThreeJS基础教程-高级几何体篇】2.5 加载GLTF/GLB格式文件,Draco压缩文件的获取与加载

加载GLTF/GLB格式文件,Draco压缩文件的获取与加载

  • 学习ThreeJS的捷径
  • 加载GL格式模型
    • 案例
    • 案例效果
    • threejs中常见的模型加载方式
    • 三种常见的gl格式文件
  • Draco压缩
    • Draco介绍
    • Draco使用过程中的常见误区
    • 如何获取Draco模型
      • gltf-pipeline
    • Draco使用案例
    • 案例效果
    • 加载Draco常见错误处理方法
  • 下一篇预告:

学习ThreeJS的捷径

本段内容会写在0篇以外所有的,本人所编写的Threejs教程中

对,学习ThreeJS有捷径
当你有哪个函数不懂的时候,第一时间去翻一翻文档
当你有哪个效果不会做的时候,第一时间去翻一翻所有的案例,也许就能找到你想要的效果
最重要的一点,就是,绝对不要怕问问题,越怕找找别人问题,你的问题就会被拖的越久

如果你确定要走WebGL/ThreeJS的开发者路线的话,以下行为可以让你更快的学习ThreeJS

  1. 没事就把所有的文档翻一遍,哪怕看不懂,也要留个印象,至少要知道Threejs有什么
  2. 没事多看看案例效果,当你记忆的案例效果足够多时,下次再遇到相似问题时,你就有可能第一时间来找对应的案例,能更快解决你自己的问题
  3. 上述案例不只是官网的案例,郭隆邦技术博客,跃焱邵隼,暮志未晚等站点均有不少优质案例,记得一并收藏
    http://www.yanhuangxueyuan.com/ 郭隆邦技术博客
    https://www.wellyyss.cn/ 跃焱邵隼
    http://www.wjceo.com/ 暮志未晚
    这三个站点是我最常逛的站点,推荐各位有事没事逛一下,看看他们的案例和写法思路,绝对没坏处

加载GL格式模型

案例

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style>
        canvas{
            display: block;
        }
        body {
            margin: 0;
            overscroll-behavior: none;
        }
        #btns{
            position: absolute;
            top:10%;
            width: 500px;
            height: 100px;
            left: 50%;
            transform:translateX(-50%);
        }
    style>
head>
<body>
<div id="btns">div>



<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js">script>

<script type="importmap">
			{
				"imports": {
					"three": "../../three.js-master/build/three.module.js"
				}
			}
		script>
<script type="module">
    import * as THREE from '../../three.js-master/build/three.module.js';
    import {OrbitControls} from "../../three.js-master/examples/jsm/controls/OrbitControls.js";
    import {GLTFLoader} from "../../three.js-master/examples/jsm/loaders/GLTFLoader.js";

    let scene,renderer,camera,orbitControls;

    let loader;

    function init(){
        scene = new THREE.Scene();
        renderer = new THREE.WebGLRenderer({
            antialias:true
        });
        renderer.setSize(window.innerWidth,window.innerHeight);
        document.body.appendChild(renderer.domElement);
        camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,0.1,50000);
        camera.position.set(10,10,10);
        orbitControls = new OrbitControls(camera,renderer.domElement);

        let helper = new THREE.AxesHelper(5);
        scene.add(helper);

        let light = new THREE.PointLight();
        camera.add(light);
        scene.add(camera);

        scene.background = new THREE.Color("#878787");

        loader = new GLTFLoader();
    }

    function addMesh(){
        loader.load("./SimpleSkinning.gltf",(gltf)=>{
            console.log(gltf);
            scene.add(gltf.scene);
        });

        loader.load("./Parrot.glb",(glb)=>{
            console.log(glb);
            let model = glb.scene;
            model.scale.setScalar(0.1);
            model.position.y += 3;
            scene.add(model);
        })

        loader.load("./glTF/MaterialsVariantsShoe.gltf",(gltf)=>{
            scene.add(gltf.scene);
            let model = gltf.scene;
            model.position.z = 3;
            model.scale.setScalar(10);
        })
    }


    function render(){
        renderer.render(scene,camera);
        requestAnimationFrame(render);
    }

    init();
    addMesh();
    render();
script>
body>
html>
	

【ThreeJS基础教程-高级几何体篇】2.5 加载GLTF/GLB格式文件,Draco压缩文件的获取与加载_第1张图片
以上模型文件均可在官方开发包 examples/models/gltf/ 文件夹下找到

案例效果

【ThreeJS基础教程-高级几何体篇】2.5 加载GLTF/GLB格式文件,Draco压缩文件的获取与加载_第2张图片

threejs中常见的模型加载方式

本次案例和前面的OBJLoader的案例几乎一致,仅仅将OBJLoader替换为了GLTFLoader,其他格式的文件也均以这样的方式加载

  1. 引入对应的Loader文件
  2. 读取模型后对加载完成后的模型对象执行一次console,在console中展开并分析其内部数据,并找到对应的Object3D对象或geometry
  3. 如果读取到的是geometry,需要你手动指定材质并手动创建mesh,如果读取到的直接是一个object3D对象,可以直接添加到scene中,如果读取到的是一组数据,那么我们需要先分析数据后再执行加载

【ThreeJS基础教程-高级几何体篇】2.5 加载GLTF/GLB格式文件,Draco压缩文件的获取与加载_第3张图片

在console中,我们可以看出,gl文件均由这几部分构成

属性名 值类型 属性说明
animations THREE.AnimationClip 模型导出时,可以选择将动画烘焙好之后,保存到模型中,gl格式读取完成后,读取到的动画就是这个,本篇暂时不谈这个对象,在后续动画部分会着重讲解
asset Object 一个对象,记录了gltf的版本号以及导出方式
cameras [THREE.Camera] 相机数组,用于读取模型内的相机
parser GLTFParser 格式转换器,可以无需关注
scene THREE.Group/Object3D/Scene 这里就是主要的模型数据,可以被添加到scene中
scenes [THREE.Group/Object3D/Scene] 场景数组,一个模型可能包含有多个场景时可以用到
userData Object 用于保存用户数据的对象

所以我们在加载完成模型后,只需要把gltf.scene作为模型对象添加到scene中即可

     //直接添加到场景中
	 scene.add(gltf.scene);

	 //或做了处理后添加到场景中
     let model = glb.scene;
     model.scale.setScalar(0.1);
     model.position.y += 3;
     scene.add(model);
	 
	 //先添加与先处理没有区别,只要你能访问到这个对象即可
	 scene.add(gltf.scene);
     let model = gltf.scene;
     model.position.z = 3;
     model.scale.setScalar(10);           

因为三个模型比例区别较大,所以笔者对三个模型的大小做了基本处理

三种常见的gl格式文件

一般来说,gl文件有三种,单独的一个gltf文件+贴图文件,glb文件+贴图文件,gltf + bin + 贴图文件,贴图文件均为非必须,根据建模师是否在建模过程中使用贴图而定

三种文件没有本质上的区别,只是gltf+bin更详细一些,数据更容易读懂,glb更方便使用一些,一般glb文件可以将贴图文件也附带到这一个文件中

Draco压缩

Draco介绍

太长了,各位看看这篇博主的文章吧,Draco库简析,没兴趣的做个了解即可,有兴趣的可以深入研究一下Draco算法

Draco在threejs中最实用的点就是压缩模型,以笔者的使用经验来说,Draco至少可以将模型压缩到10%甚至更小,文件越大压缩率越高,比如说我一个50M的中高模型,使用Draco技术能压缩到差不多5M甚至更小,但是如果我一个5M的模型,压缩后差不多能到2M这样

Draco使用过程中的常见误区

  1. Draco压缩,可以把文件大小压下来,但是笔者在使用过程中也出现了不少次的坏面破面,不同的模型执行压缩的情况,均有不同
  2. 不要仗着Draco能大幅压缩文件,就可以随意上高精度模型,Draco压缩只能缩小文件大小,不但不能降低你程序的内存占用,反而会提升你的CPU使用率和一定的内存占用,如果你的模型大小在你的带宽承受范围内,已经达到了一个比较流畅的情况,此时就可以不用Draco压缩

如何获取Draco模型

gltf-pipeline

https://github.com/CesiumGS/gltf-pipeline
这个插件在上一篇【ThreeJS基础教程-高级几何体篇】2.4 GL格式(GLTF/GLB)模型讲解与其他常用模型格式介绍中已经提到,当你的环境中已经有了gltf-pipeline之后,babylon插件在导出gltf模型的时候,就会增加压缩模型的选项
【ThreeJS基础教程-高级几何体篇】2.5 加载GLTF/GLB格式文件,Draco压缩文件的获取与加载_第4张图片
这个插件也可以单独使用

安装该插件,建议安装到全局\

	npm install -g gltf-pipeline

使用时,在模型的文件夹下,shift+右键打开powershell来使用即可
转换gltf和glb文件

	gltf-pipeline -i model.gltf -o model.glb
	
	gltf-pipeline -i model.gltf -b
	
	gltf-pipeline -i model.glb -o model.gltf
	
	gltf-pipeline -i model.glb -j

draco压缩

	gltf-pipeline -i model.gltf -o modelDraco.gltf -d

其他用法可以去github查看

Draco使用案例

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style>
        canvas{
            display: block;
        }
        body {
            margin: 0;
            overscroll-behavior: none;
        }
        #btns{
            position: absolute;
            top:10%;
            width: 500px;
            height: 100px;
            left: 50%;
            transform:translateX(-50%);
        }
    style>
head>
<body>
<div id="btns">div>



<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js">script>

<script type="importmap">
			{
				"imports": {
					"three": "../../three.js-master/build/three.module.js"
				}
			}
		script>
<script type="module">
    import * as THREE from '../../three.js-master/build/three.module.js';
    import {OrbitControls} from "../../three.js-master/examples/jsm/controls/OrbitControls.js";
    import {GLTFLoader} from "../../three.js-master/examples/jsm/loaders/GLTFLoader.js";
    import {DRACOLoader} from "../../three.js-master/examples/jsm/loaders/DRACOLoader.js";

    let scene,renderer,camera,orbitControls;

    let loader,dracoLoader;

    function init(){
        scene = new THREE.Scene();
        renderer = new THREE.WebGLRenderer({
            antialias:true
        });
        renderer.setSize(window.innerWidth,window.innerHeight);
        document.body.appendChild(renderer.domElement);
        camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,0.1,50000);
        camera.position.set(5,5,5);
        orbitControls = new OrbitControls(camera,renderer.domElement);

        let helper = new THREE.AxesHelper(5);
        scene.add(helper);

        let light = new THREE.PointLight();
        camera.add(light);
        scene.add(camera);

        scene.background = new THREE.Color("#878787");

        dracoLoader = new DRACOLoader().setDecoderPath("../../three.js-master/examples/js/libs/draco/gltf/");

        loader = new GLTFLoader().setDRACOLoader(dracoLoader);
    }

    function addMesh(){
        loader.load("./dracoModel/IridescentDishWithOlives.glb",(glb)=>{
            console.log(glb)
            scene.add(glb.scene);
            glb.scene.scale.setScalar(10);
        })
    }


    function render(){
        renderer.render(scene,camera);
        requestAnimationFrame(render);
    }

    init();
    addMesh();
    render();
script>
body>
html>

案例效果

【ThreeJS基础教程-高级几何体篇】2.5 加载GLTF/GLB格式文件,Draco压缩文件的获取与加载_第5张图片

这里使用的模型为examples/models/gltf/IridescentDishWithOlives.glb,这个模型为官方案例所使用的模型

加载Draco常见错误处理方法

  1. 注意引用路径是否正确,draco有一个专门的解压文件库的路径,里面包含了四个文件,如果你使用的是ES6的引入方式,在jsm的文件夹下是找不到的,文件在这个位置:

【ThreeJS基础教程-高级几何体篇】2.5 加载GLTF/GLB格式文件,Draco压缩文件的获取与加载_第6张图片

  1. 检查你的文件是否执行过draco压缩,一般来说,windows自带的模型查看器直接可以打开gltf/glb文件,但是不能直接打开draco压缩后的gltf/glb,可以通过这个判断你的模型是否经历过draco压缩

  2. 使用threejs/editor或babylon模型沙盒检查模型是否可以被加载出来,如果这个模型在这两个编辑器内无法被加载出来,那么在你的程序中也依然无法加载,需重新处理模型

如果加载模型时未报错,请查看笔者前面的文章【ThreeJS基础教程-高级几何体篇】2.2 加载模型,加载模型时的常见错误

下一篇预告:

BufferGeometry介绍

你可能感兴趣的:(WebGL,ThreeJS,javascript,前端)