博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

pipeline调用Draco来压缩glb模型

Posted on 2022-09-09 15:25  地霊殿~三無  阅读(1810)  评论(2编辑  收藏  举报

一、前言

最近得空了,来试试之前了解的pipeline插件,先给大家简单介绍一下这款插件,再带大家试试效果。

二、pipeline

gltf-pipeline是一个gltf/glb模型的nodejs类库,使用此类库能够对gltf模型做进一步的处理,处理完成的gltf/glb模型,一般是将贴图文件包含到模型内容中。

它有以下几种作用

  • 将 glTF 转换为 glb(和反向)
  • 将缓冲区/纹理保存为嵌入或单独的文件,如果是纹理太大,可以用这种方法分离出来,再另外压缩图片文件
  • 将 glTF 1.0 模型转换为 glTF 2.0(使用KHR_techniques_webglKHR_blend扩展)
  • 应用Draco网格压缩

它有以下几种常见的命令参数

image.png

如果需要了解更多相关细节,可以访问官网npmmirror.com/package/glt…

三、实验过程

大模型有了,刚用obj2gltf转的,不过加载例子是用的小模型。

1、安装

  npm install -g gltf-pipeline
复制代码

2、压缩试验

a、压缩小模型

在目录下控制台输入下面命令,把test.glb压缩后输出成test-pipeline.glb文件(源文件还在的,放心),该命令要求node版本最低为12噢。太低版本建议用nvm管理工具切换一下。

gltf-pipeline -i test.glb -o test-pipeline.glb -d
复制代码

可以看到,大小从原先的90k变成现在的13k,压缩了将近百分之85。 image.png

b、压缩大模型

下面是压缩大模型的,这个就更明显了,从77.3m到845k

gltf-pipeline -i earth.gltf -o earth-pipeline.glb -d
复制代码

image.png

c、 不带d进行压缩

如果我是用以下不带d的命令压缩

 gltf-pipeline -i test.glb -o test-pipeline-notd.glb
复制代码

可以看出,对于小模型来说,大小是基本没有变化的

image.png

但对大模型而言,还有有的,从77.3m到57.9m,缩小还是挺明显的。

image.png

这种情况下可以正常导入的,不用额外引入DRACOLoader

image.png

3、导入-d压缩的模型

a、导入原先的模型

initLoad2() {
  // 加载
  this.gltLoader2 = new THREE.GLTFLoader()
  this.gltLoader2.load('/assets/gltf-format-big/test.glb', (gltf) => {
    console.log(gltf)
    gltf.scene.position.x = -6
    gltf.scene.position.z = 4
    gltf.scene.position.y = 0
    gltf.scene.children[0].children.forEach((item, i) => {
      gltf.scene.children[0].children[i].castShadow = true
      gltf.scene.children[0].children[i].receiveShadow = true
    })
    gltf.scene.rotateY(0.5 * Math.PI)
    this.scene.add(gltf.scene)
  },
  // 加载进度回调
  (xhr) => {
    console.log(xhr, (xhr.loaded / xhr.total) * 100 + '% loaded')
  },
  )
}
复制代码

} 效果图如下 image.png

b、导入压缩后的模型

按原先方法导入,会报以下的错误,必须引入DRACOLoader image.png

c、DRACOLoader使用

引入1 : 在public下index.html直接引入

<script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/loaders/DRACOLoader.js"></script>
复制代码

引入2 :按需引入

这个文件在three的包是有集成的,本项目是按需引入的,在对应文件引入下面这个, 也可以在main.js全局引入

   import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
   
复制代码

然后是找到node_modules下的three文件夹,赋值到public文件夹下,这一步是为了给dracoloader设置Draco解码库 解压路径用的,一会gltfloader也要同步设置

image.png

image.png

特别是浏览器遇到这种情况的,一定要上述步骤放到public文件夹下

  Uncaught SyntaxError: Unexpected token ‘<‘
复制代码

用下列代码加载压缩后的模型

  initLoad2() {
  // 加载
  this.gltLoader2 = new THREE.GLTFLoader()
  
  const dracoLoader = new DRACOLoader()
  // 这个路径默认开始是public
  // 设置Draco解码库 解压路径,该路径就是解压文件所在的位置
  dracoLoader.setDecoderPath('/three/examples/js/libs/draco/gltf/')
  // dracoLoader.setDecoderConfig({ type: 'js' }) // 设置兼容性强的解码器,如果加载不出来,就设置下这个
  // DRACOLoader预加载
  dracoLoader.preload()
  // 设置gltfloader解压loader
  this.gltLoader2.setPath('/three/examples/js/libs/draco/gltf/')
  this.gltLoader2.setDRACOLoader(dracoLoader)
  this.gltLoader2.load('/assets/gltf-format-big/test-pipeline.glb', (gltf) => {
    console.log(gltf)
    gltf.scene.position.x = -6
    gltf.scene.position.z = 4
    gltf.scene.position.y = 0
    gltf.scene.children[0].children.forEach((item, i) => {
      gltf.scene.children[0].children[i].castShadow = true
      gltf.scene.children[0].children[i].receiveShadow = true
    })
    // gltf.scene.scale.set(0.1, 0.1, 0.1)
    gltf.scene.rotateY(0.5 * Math.PI)
    this.scene.add(gltf.scene)
  },
  // 加载进度回调
  (xhr) => {
    console.log(xhr, (xhr.loaded / xhr.total) * 100 + '% loaded')
  }
  )
}
复制代码

image.png image.png

真不愧是draco有损压缩,加载是成功了,但原本的轮廓已经看不到了,还多了一个巨大的单面。我试了多个模型,都发现存在这个问题。目前还在寻找解决方法。有知道的朋友可以告诉我一下吗?

如果不加-d,那就不用引入dracoloader加载器,但是压缩效果又不够明显。

ps: 不知道是我模型的问题还是别的,明天我再试一下。这个压缩好多坑,网上资料来来去去就那几个,还都不一样,只能慢慢试了。

Snipaste_2022-07-19_15-30-26.jpg


作者:地霊殿__三無
链接:https://juejin.cn/post/7131028565335736356
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Live2D