添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a use case in which I am trying to load a GLTF file which is compressed using DRACO-Compression. I am able to run it using plain javascript but I am facing issues integrating the loader with ReactJs.

What I am doing:

  • Copying the draco library from here into my application's scope - https://github.com/mrdoob/three.js/tree/master/examples/js/libs/draco
  • Copying the DRACOLoader.js from here into my application's scope - https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/DRACOLoader.js
  • Exporting it as a THREE.DRACOLoader Module in my application where I need it
  • The error I am getting - DracoDecoderModule is not defined

    In my app, this is how I am importing:

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

    It is recommended to use https://www.gstatic.com/draco/v1/decoders/ as the decoder source directory, e.g.:

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

    See example https://github.com/google/draco/tree/master/javascript/example.

    Relative paths won't work. One way to achieve this is by either hosting your draco_wasm_wrapper.js on like aws or something like that or you could try the following:

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

    Import your dependencies:

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

    Create and configue your draco loader:

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

    Create and configure your gltf loader:

    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)
    

    I like the answer from @marrion luaka (and upvoted it) but referencing locally.

    Only changed:

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

    To this:

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

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

    worked for me.

    if you do like this,

    DRACOLoader.setDecoderPath('./draco/')
    

    then react will take it as,

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

    so it wont work.

    None of the above worked directly for me on three@0.115.0 so I used:

    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;
    

    BONUS for those who like promises, I've also been making my loaders return promises with the following:

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

    Example usage:

    import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
    export const fbxLoader = promisify(new FBXLoader());
    

    Then elsewhere:

    import { fbxLoader } from './loaders'
    fbxLoader.load('cat.fbx').then(model => {
      console.log(model)
    

    Perhaps another option (for React only).

    I copied the three required files from node_modules to public, in a folder called 'draco'.

    const gltfLoader = new GLTFLoader()
    const dracoLoader = new DRACOLoader()  // allow for DRACO compression
    dracoLoader.setDecoderPath(process.env.PUBLIC_URL + '/draco/')
    gltfLoader.setDRACOLoader(dracoLoader)
    

    I am using Webpack in a similar way to how Create React App uses it. Here is how I got the Draco decoder path working.

  • In your app's public folder, create a new folder called draco.

  • Download the four files found in the Three.js Draco Examples and move them into your public/draco folder.

  • Use this code:

    // Imports
    import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
    import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
    // Create a new DRACO loader (for decompressing compressed GLTF models)
    const dracoLoader = new DRACOLoader();
    // Set the DRACO loader's decoder path to the `public/draco` folder
    // NB: You have to manually download and copy/paste the files from 
    // https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/draco/gltf
    // into this folder.
    dracoLoader.setDecoderPath('./draco/');
    // Create a new GLTF loader
    const gltfLoader = new GLTFLoader();
    // Use the DRACO loader with the GLTF loader
    gltfLoader.setDRACOLoader(dracoLoader);
    

    It is recommended to use https://www.gstatic.com/draco/versioned/decoders/[version]/ as the decoder source directory, e.g.:

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

    Using the versioned www.gstatic.com WASM and Javascript decoders is recommended since v1.4.1, as stated here.

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.

  •