使用 Three.js 和本地 Draco Loader 高效加载压缩 GLB 模型

在前端项目中,使用 Three.js 渲染 3D 模型时,经常会遇到模型文件过大的问题。为了优化加载速度和传输带宽,很多 GLB 模型都会使用 Draco 压缩。然而,直接加载压缩模型可能会遇到 404 错误或解码失败,尤其是使用官方 CDN 或本地开发时。本文将手把手教你如何在 Vue + Three.js 项目中使用本地 Draco Loader,加载压缩 GLB 模型。

一、Draco 简介

Draco 是 Google 开发的 3D 几何压缩库,可以将几何数据压缩到原来的 10~30% 左右,同时支持 顶点、法线、纹理坐标 压缩。Three.js 提供了 DRACOLoader 来解析压缩的 GLB/GLTF 模型。

官方 CDN 地址:https://www.gstatic.com/draco/v1/decoders/
但在本地开发时,使用 CDN 可能会遇到 跨域限制404,因此建议把 Draco 文件放在项目的 public 目录下。

二、准备工作

1. 安装 Three.js

npm install three

2. 获取 Draco 解码器文件

three 包中,Draco 文件位于:

node_modules/three/examples/jsm/libs/draco/

主要文件包括:

  • draco_decoder.js

  • draco_decoder.wasm

  • draco_wasm_wrapper.js

  • draco_wasm_wrapper.wasm

3. 复制文件到 public 目录

# 创建 draco 文件夹
New-Item -ItemType Directory -Force .\public\draco

# 复制解码器文件
Copy-Item -Path .\node_modules\three\examples\jsm\libs\draco\* -Destination .\public\draco\

确保目录结构如下:

public/
  draco/
    draco_decoder.js
    draco_decoder.wasm
    draco_wasm_wrapper.js
    draco_wasm_wrapper.wasm

<template>
  <div ref="threeCanvas" style="width: 100%; height: 100vh;"></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';

const threeCanvas = ref(null);
let scene, camera, renderer, controls;

function initScene() {
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
  camera.position.set(0, 2, 5);

  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(window.innerWidth, window.innerHeight);
  threeCanvas.value.appendChild(renderer.domElement);

  controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;

  // 光源
  const ambient = new THREE.AmbientLight(0xffffff, 0.8);
  const dir = new THREE.DirectionalLight(0xffffff, 1);
  dir.position.set(5, 10, 7);
  scene.add(ambient, dir);

  window.addEventListener('resize', onWindowResize);
}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

async function loadModel() {
  const loader = new GLTFLoader();

  const dracoLoader = new DRACOLoader();
  dracoLoader.setDecoderPath('/draco/'); // ⚡ 指向 public/draco
  dracoLoader.preload();
  loader.setDRACOLoader(dracoLoader);

  loader.load('/models/test-pipeline.glb', gltf => {
    scene.add(gltf.scene);
  }, undefined, err => {
    console.error('加载模型出错', err);
  });
}

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

onMounted(async () => {
  initScene();
  await loadModel();
  animate();
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', onWindowResize);
  renderer.dispose();
});
</script>

浏览器访问:

http://localhost:8080/draco/draco_wasm_wrapper.js

如果能访问文件,说明本地 Draco 已经生效。

我文章里面有在线引入报错所以使用本地化引入解决

### Vue3 中使用 Three.js 实现 Draco 压缩模型加载与展示 在 Vue3 Three.js 的环境中,可以通过引入 `DRACOLoader` 来实现对经过 Draco 压缩后的 GLTF 或 GLB 模型文件的加载渲染。以下是具体的实现方法: #### 1. 安装依赖 为了支持 Draco 压缩功能,需要安装必要的库: ```bash npm install three @loaders.gl/draco ``` #### 2. 配置 DRACOLoader加载模型 通过配置 `GLTFLoader` `DRACOLoader`,可以完成对压缩模型的解压加载。 ```javascript import * as THREE from 'three'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; // 创建场景、相机渲染器 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 初始化 DRACOLoader const dracoLoader = new DRACOLoader(); dracoLoader.setDecoderPath('https://www.gstatic.com/draco/v1/decoders/'); // 设置解码路径 dracoLoader.preload(); // 提前预加载解码器 // 使用 GLTFLoader 加载模型并设置 DRACOLoader const loader = new GLTFLoader(); loader.setDRACOLoader(dracoLoader); // 将 DRACOLoader 绑定到 GLTFLoader 上 // 加载模型 loader.load( '/path/to/compressed-model.glb', // 替换为实际的模型路径 (gltf) => { const model = gltf.scene; scene.add(model); // 添加模型到场景中 console.log(gltf); // 查看模型的结构属性[^1] animate(); }, undefined, (error) => { console.error(error); } ); function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } ``` 上述代码展示了如何初始化 `DRACOLoader` 并将其绑定至 `GLTFLoader`,从而成功加载Draco 压缩过的 `.glb` 文件[^2]。 #### 3. 显示模型元素结构属性 当模型加载完成后,可以在控制台打印出其内部结构属性。例如,在回调函数中访问 `gltf.scene.children` 可以查看模型的具体节点及其材质、几何体等信息。 ```javascript console.log(gltf.scene.children.map(child => ({ name: child.name || '(unnamed)', type: child.type, material: child.material ? child.material.name : null, geometry: child.geometry ? child.geometry.parameters : null }))); ``` 这会返回一个数组,其中包含了每个子对象的名字、类型、材质以及几何参数的信息。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值