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.