如何在 ReactJs 中使用 DRACOLoader 和 GLTFLoader?

Posted

技术标签:

【中文标题】如何在 ReactJs 中使用 DRACOLoader 和 GLTFLoader?【英文标题】:How to use DRACOLoader with GLTFLoader in ReactJs? 【发布时间】:2019-09-28 00:26:44 【问题描述】:

我有一个用例,我试图加载一个使用 DRACO-Compression 压缩的 GLTF 文件。我可以使用纯 javascript 运行它,但我在将加载器与 ReactJs 集成时遇到了问题。

我在做什么:

将 draco 库从这里复制到我的应用程序范围 - https://github.com/mrdoob/three.js/tree/master/examples/js/libs/draco 将 DRACOLoader.js 从这里复制到我的应用程序范围 - https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/DRACOLoader.js 在我需要它的应用程序中将其导出为 THREE.DRACOLoader 模块

我得到的错误 - DracoDecoderModule 未定义

在我的应用程序中,我是这样导入的:

  import DRACOLoader from './DRACOLoader'
  DRACOLoader.setDecoderPath('./draco/')

【问题讨论】:

【参考方案1】:

然后在云中托管 draco 文件夹

import DRACOLoader from './DRACOLoader';
DRACOLoader.setDecoderPath(path to hosted draco folder);

为我工作。

如果你这样做,

DRACOLoader.setDecoderPath('./draco/')

那么react就会把它当做,

DRACOLoader.setDecoderPath('localhost:3000/draco/');

所以它不会工作。

【讨论】:

【参考方案2】:

相对路径不起作用。实现此目的的一种方法是将您的 draco_wasm_wrapper.js 托管在类似 aws 或类似的东西上,或者您可以尝试以下方法:

npm i -S three // make sure you have the latest threejs package v2 and up

导入你的依赖:

import  GLTFLoader  from 'three/examples/jsm/loaders/GLTFLoader'
import  DRACOLoader  from 'three/examples/jsm/loaders/DRACOLoader'

创建和配置你的 draco 加载器:

const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/js/libs/draco/'); // use a full url path

创建和配置你的 gltf 加载器:

const gltf = new GLTFLoader();
gltf.setDRACOLoader(dracoLoader);

// then you can load your glb file
const glbPath = 'your glb file'
gltf.load(glbPath, function(gltf) 
  console.log(gltf)
)

【讨论】:

【参考方案3】:

我喜欢@marrion luaka 的答案(并赞成),但在本地引用。

只是改变了:

dracoLoader.setDecoderPath('https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/js/libs/draco/'); // use a full url path

到这里:

dracoLoader.setDecoderPath( '../node_modules/three/examples/js/libs/draco/gltf/' );

【讨论】:

【参考方案4】:

以上都没有直接为我在three@0.115.0上工作,所以我使用了:

import  GLTFLoader  from 'three/examples/jsm/loaders/GLTFLoader';
import  DRACOLoader  from 'three/examples/jsm/loaders/DRACOLoader';
import * as THREE from 'three';

// draco
const draco = new DRACOLoader()
draco.setDecoderPath('../node_modules/three/examples/js/libs/draco/gltf/');
draco.setDecoderConfig( type: 'js' );
export const dracoLoader = draco;

// gltf
const gltf = new GLTFLoader();
gltf.setDRACOLoader( dracoLoader );
export const gltfLoader = gltf;

对于那些喜欢承诺的人来说,我也一直在让我的装载机返回承诺:

function promisify(loader, onProgress) 
  function promiseLoader(url) 
    return new Promise((resolve, reject) => 
      loader.load(url, resolve, onProgress, reject);
    );
  
  return 
    originalLoader: loader,
    load: promiseLoader,
  ;

示例用法:

import  FBXLoader  from 'three/examples/jsm/loaders/FBXLoader';

export const fbxLoader = promisify(new FBXLoader());

然后在别处:

import  fbxLoader  from './loaders'

fbxLoader.load('cat.fbx').then(model => 
  console.log(model)
)

【讨论】:

【参考方案5】:

推荐使用https://www.gstatic.com/draco/v1/decoders/作为解码器源目录,例如:

const draco = new DRACOLoader();
draco.setDecoderConfig( type: 'js' );
draco.setDecoderPath('https://www.gstatic.com/draco/v1/decoders/');

参见示例https://github.com/google/draco/tree/master/javascript/example。

【讨论】:

以上是关于如何在 ReactJs 中使用 DRACOLoader 和 GLTFLoader?的主要内容,如果未能解决你的问题,请参考以下文章

如何在两个不同的组件中使用路由 - ReactJS

如何在ReactJS中使用JQuery

如何在 reactJS 中使用 Thymeleaf th:text

如何在 ReactJS 中使用 VideoJS 插件?

如何在 ReactJS 中使用 cloudinary?

ReactJs - 如何在一个组件中使用多个子组件